kanidm/docs/v1.1.0-alpha.3/rustdoc/src/kanidm_proto/v1.rs.html
2022-04-29 03:14:30 +00:00

1942 lines
115 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 `kanidm_proto/src/v1.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>v1.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 src="../../crates.js"></script><script defer src="../../main.js"></script><script defer src="../../source-script.js"></script><script defer src="../../source-files.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="../../kanidm_proto/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="../../kanidm_proto/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="../../kanidm_proto/index.html"><img class="rust-logo" src="../../rust-logo.svg" alt="logo"></a><nav class="sub"><div class="theme-picker hidden"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"><img width="22" height="22" alt="Pick another theme!" src="../../brush.svg"></button><div id="theme-choices" role="menu"></div></div><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"><button type="button" id="help-button" title="help">?</button><a id="settings-menu" href="../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../wheel.svg"></a></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>
<span id="925">925</span>
<span id="926">926</span>
<span id="927">927</span>
<span id="928">928</span>
<span id="929">929</span>
<span id="930">930</span>
<span id="931">931</span>
<span id="932">932</span>
<span id="933">933</span>
<span id="934">934</span>
<span id="935">935</span>
<span id="936">936</span>
<span id="937">937</span>
<span id="938">938</span>
<span id="939">939</span>
<span id="940">940</span>
<span id="941">941</span>
<span id="942">942</span>
<span id="943">943</span>
<span id="944">944</span>
<span id="945">945</span>
<span id="946">946</span>
<span id="947">947</span>
<span id="948">948</span>
<span id="949">949</span>
<span id="950">950</span>
<span id="951">951</span>
<span id="952">952</span>
<span id="953">953</span>
<span id="954">954</span>
<span id="955">955</span>
<span id="956">956</span>
<span id="957">957</span>
<span id="958">958</span>
<span id="959">959</span>
<span id="960">960</span>
<span id="961">961</span>
<span id="962">962</span>
<span id="963">963</span>
<span id="964">964</span>
<span id="965">965</span>
<span id="966">966</span>
<span id="967">967</span>
</pre><pre class="rust"><code><span class="kw">use</span> <span class="ident">serde</span>::{<span class="ident">Deserialize</span>, <span class="ident">Serialize</span>};
<span class="kw">use</span> <span class="ident">std::cmp::Ordering</span>;
<span class="kw">use</span> <span class="ident">std::collections::BTreeMap</span>;
<span class="kw">use</span> <span class="ident">std::fmt</span>;
<span class="kw">use</span> <span class="ident">uuid::Uuid</span>;
<span class="kw">use</span> <span class="ident">webauthn_rs::proto</span>::{
<span class="ident">CreationChallengeResponse</span>, <span class="ident">PublicKeyCredential</span>, <span class="ident">RegisterPublicKeyCredential</span>,
<span class="ident">RequestChallengeResponse</span>,
};
<span class="comment">// These proto implementations are here because they have public definitions</span>
<span class="comment">/* ===== errors ===== */</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Debug</span>, <span class="ident">PartialEq</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">SchemaError</span> {
<span class="ident">NotImplemented</span>,
<span class="ident">NoClassFound</span>,
<span class="ident">InvalidClass</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>),
<span class="ident">MissingMustAttribute</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>),
<span class="ident">InvalidAttribute</span>(<span class="ident">String</span>),
<span class="ident">InvalidAttributeSyntax</span>(<span class="ident">String</span>),
<span class="ident">EmptyFilter</span>,
<span class="ident">Corrupted</span>,
<span class="ident">PhantomAttribute</span>(<span class="ident">String</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Debug</span>, <span class="ident">PartialEq</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">PluginError</span> {
<span class="ident">AttrUnique</span>(<span class="ident">String</span>),
<span class="ident">Base</span>(<span class="ident">String</span>),
<span class="ident">ReferentialIntegrity</span>(<span class="ident">String</span>),
<span class="ident">PasswordImport</span>(<span class="ident">String</span>),
<span class="ident">Oauth2Secrets</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Debug</span>, <span class="ident">PartialEq</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">ConsistencyError</span> {
<span class="ident">Unknown</span>,
<span class="comment">// Class, Attribute</span>
<span class="ident">SchemaClassMissingAttribute</span>(<span class="ident">String</span>, <span class="ident">String</span>),
<span class="ident">SchemaClassPhantomAttribute</span>(<span class="ident">String</span>, <span class="ident">String</span>),
<span class="ident">SchemaUuidNotUnique</span>(<span class="ident">Uuid</span>),
<span class="ident">QueryServerSearchFailure</span>,
<span class="ident">EntryUuidCorrupt</span>(<span class="ident">u64</span>),
<span class="ident">UuidIndexCorrupt</span>(<span class="ident">String</span>),
<span class="ident">UuidNotUnique</span>(<span class="ident">String</span>),
<span class="ident">RefintNotUpheld</span>(<span class="ident">u64</span>),
<span class="ident">MemberOfInvalid</span>(<span class="ident">u64</span>),
<span class="ident">InvalidAttributeType</span>(<span class="ident">String</span>),
<span class="ident">DuplicateUniqueAttribute</span>(<span class="ident">String</span>),
<span class="ident">InvalidSpn</span>(<span class="ident">u64</span>),
<span class="ident">SqliteIntegrityFailure</span>,
<span class="ident">BackendAllIdsSync</span>,
<span class="ident">BackendIndexSync</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Debug</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">PasswordFeedback</span> {
<span class="comment">// https://docs.rs/zxcvbn/latest/zxcvbn/feedback/enum.Suggestion.html</span>
<span class="ident">UseAFewWordsAvoidCommonPhrases</span>,
<span class="ident">NoNeedForSymbolsDigitsOrUppercaseLetters</span>,
<span class="ident">AddAnotherWordOrTwo</span>,
<span class="ident">CapitalizationDoesntHelpVeryMuch</span>,
<span class="ident">AllUppercaseIsAlmostAsEasyToGuessAsAllLowercase</span>,
<span class="ident">ReversedWordsArentMuchHarderToGuess</span>,
<span class="ident">PredictableSubstitutionsDontHelpVeryMuch</span>,
<span class="ident">UseALongerKeyboardPatternWithMoreTurns</span>,
<span class="ident">AvoidRepeatedWordsAndCharacters</span>,
<span class="ident">AvoidSequences</span>,
<span class="ident">AvoidRecentYears</span>,
<span class="ident">AvoidYearsThatAreAssociatedWithYou</span>,
<span class="ident">AvoidDatesAndYearsThatAreAssociatedWithYou</span>,
<span class="comment">// https://docs.rs/zxcvbn/latest/zxcvbn/feedback/enum.Warning.html</span>
<span class="ident">StraightRowsOfKeysAreEasyToGuess</span>,
<span class="ident">ShortKeyboardPatternsAreEasyToGuess</span>,
<span class="ident">RepeatsLikeAaaAreEasyToGuess</span>,
<span class="ident">RepeatsLikeAbcAbcAreOnlySlightlyHarderToGuess</span>,
<span class="ident">ThisIsATop10Password</span>,
<span class="ident">ThisIsATop100Password</span>,
<span class="ident">ThisIsACommonPassword</span>,
<span class="ident">ThisIsSimilarToACommonlyUsedPassword</span>,
<span class="ident">SequencesLikeAbcAreEasyToGuess</span>,
<span class="ident">RecentYearsAreEasyToGuess</span>,
<span class="ident">AWordByItselfIsEasyToGuess</span>,
<span class="ident">DatesAreOftenEasyToGuess</span>,
<span class="ident">NamesAndSurnamesByThemselvesAreEasyToGuess</span>,
<span class="ident">CommonNamesAndSurnamesAreEasyToGuess</span>,
<span class="comment">// Custom</span>
<span class="ident">TooShort</span>(<span class="ident">usize</span>),
<span class="ident">BadListed</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Debug</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">OperationError</span> {
<span class="ident">SessionExpired</span>,
<span class="ident">EmptyRequest</span>,
<span class="ident">Backend</span>,
<span class="ident">NoMatchingEntries</span>,
<span class="ident">NoMatchingAttributes</span>,
<span class="ident">CorruptedEntry</span>(<span class="ident">u64</span>),
<span class="ident">CorruptedIndex</span>(<span class="ident">String</span>),
<span class="ident">ConsistencyError</span>(<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="ident">SchemaViolation</span>(<span class="ident">SchemaError</span>),
<span class="ident">Plugin</span>(<span class="ident">PluginError</span>),
<span class="ident">FilterGeneration</span>,
<span class="ident">FilterUuidResolution</span>,
<span class="ident">InvalidAttributeName</span>(<span class="ident">String</span>),
<span class="ident">InvalidAttribute</span>(<span class="ident">String</span>),
<span class="ident">InvalidDbState</span>,
<span class="ident">InvalidCacheState</span>,
<span class="ident">InvalidValueState</span>,
<span class="ident">InvalidEntryId</span>,
<span class="ident">InvalidRequestState</span>,
<span class="ident">InvalidState</span>,
<span class="ident">InvalidEntryState</span>,
<span class="ident">InvalidUuid</span>,
<span class="ident">InvalidReplChangeId</span>,
<span class="ident">InvalidAcpState</span>(<span class="ident">String</span>),
<span class="ident">InvalidSchemaState</span>(<span class="ident">String</span>),
<span class="ident">InvalidAccountState</span>(<span class="ident">String</span>),
<span class="ident">BackendEngine</span>,
<span class="ident">SqliteError</span>, <span class="comment">//(RusqliteError)</span>
<span class="ident">FsError</span>,
<span class="ident">SerdeJsonError</span>,
<span class="ident">SerdeCborError</span>,
<span class="ident">AccessDenied</span>,
<span class="ident">NotAuthenticated</span>,
<span class="ident">NotAuthorised</span>,
<span class="ident">InvalidAuthState</span>(<span class="ident">String</span>),
<span class="ident">InvalidSessionState</span>,
<span class="ident">SystemProtectedObject</span>,
<span class="ident">SystemProtectedAttribute</span>,
<span class="ident">PasswordQuality</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">PasswordFeedback</span><span class="op">&gt;</span>),
<span class="ident">CryptographyError</span>,
<span class="ident">ResourceLimit</span>,
<span class="ident">QueueDisconnected</span>,
<span class="ident">Webauthn</span>,
<span class="ident">Wait</span>(<span class="ident">time::OffsetDateTime</span>),
}
<span class="kw">impl</span> <span class="ident">PartialEq</span> <span class="kw">for</span> <span class="ident">OperationError</span> {
<span class="kw">fn</span> <span class="ident">eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) -&gt; <span class="ident">bool</span> {
<span class="comment">// We do this to avoid InvalidPassword being checked as it&#39;s not</span>
<span class="comment">// derive PartialEq. Generally we only use the PartialEq for TESTING</span>
<span class="comment">// anyway.</span>
<span class="ident">std::mem::discriminant</span>(<span class="self">self</span>) <span class="op">==</span> <span class="ident">std::mem::discriminant</span>(<span class="ident">other</span>)
}
}
<span class="comment">/* ===== higher level types ===== */</span>
<span class="comment">// These are all types that are conceptually layers ontop of entry and</span>
<span class="comment">// friends. They allow us to process more complex requests and provide</span>
<span class="comment">// domain specific fields for the purposes of IDM, over the normal</span>
<span class="comment">// entry/ava/filter types. These related deeply to schema.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Group</span> {
<span class="kw">pub</span> <span class="ident">name</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">uuid</span>: <span class="ident">String</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">Group</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;[ name: {}, &quot;</span>, <span class="self">self</span>.<span class="ident">name</span>)<span class="question-mark">?</span>;
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;uuid: {} ]&quot;</span>, <span class="self">self</span>.<span class="ident">uuid</span>)
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Claim</span> {
<span class="kw">pub</span> <span class="ident">name</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">uuid</span>: <span class="ident">String</span>,
<span class="comment">// These can be ephemeral, or shortlived in a session.</span>
<span class="comment">// some may even need requesting.</span>
<span class="comment">// pub expiry: DateTime</span>
}
<span class="comment">/*
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Application {
pub name: String,
pub uuid: String,
}
*/</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>, <span class="ident">Ord</span>, <span class="ident">PartialOrd</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">AuthType</span> {
<span class="ident">Anonymous</span>,
<span class="ident">UnixPassword</span>,
<span class="ident">Password</span>,
<span class="ident">GeneratedPassword</span>,
<span class="ident">Webauthn</span>,
<span class="ident">PasswordMfa</span>,
<span class="comment">// PasswordWebauthn,</span>
<span class="comment">// WebauthnVerified,</span>
<span class="comment">// PasswordWebauthnVerified,</span>
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">AuthType</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AuthType::Anonymous</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;anonymous&quot;</span>),
<span class="ident">AuthType::UnixPassword</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;unixpassword&quot;</span>),
<span class="ident">AuthType::Password</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;password&quot;</span>),
<span class="ident">AuthType::GeneratedPassword</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;generatedpassword&quot;</span>),
<span class="ident">AuthType::Webauthn</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;webauthn&quot;</span>),
<span class="ident">AuthType::PasswordMfa</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;passwordmfa&quot;</span>),
}
}
}
<span class="doccomment">/// The currently authenticated user, and any required metadata for them</span>
<span class="doccomment">/// to properly authorise them. This is similar in nature to oauth and the krb</span>
<span class="doccomment">/// PAC/PAD structures. Currently we only use this internally, but we should</span>
<span class="doccomment">/// consider making it &quot;parseable&quot; by the client so they can have per-session</span>
<span class="doccomment">/// group/authorisation data.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This structure and how it works will *very much* change over time from this</span>
<span class="doccomment">/// point onward!</span>
<span class="doccomment">///</span>
<span class="doccomment">/// It&#39;s likely that this must have a relationship to the server&#39;s user structure</span>
<span class="doccomment">/// and to the Entry so that filters or access controls can be applied.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">UserAuthToken</span> {
<span class="kw">pub</span> <span class="ident">session_id</span>: <span class="ident">Uuid</span>,
<span class="kw">pub</span> <span class="ident">auth_type</span>: <span class="ident">AuthType</span>,
<span class="comment">// When this token should be considered expired. Interpretation</span>
<span class="comment">// may depend on the client application.</span>
<span class="kw">pub</span> <span class="ident">expiry</span>: <span class="ident">time::OffsetDateTime</span>,
<span class="kw">pub</span> <span class="ident">uuid</span>: <span class="ident">Uuid</span>,
<span class="comment">// pub name: String,</span>
<span class="kw">pub</span> <span class="ident">displayname</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">spn</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">mail_primary</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="comment">// pub groups: Vec&lt;Group&gt;,</span>
<span class="comment">// Should we just retrieve these inside the server instead of in the uat?</span>
<span class="comment">// or do we want per-session limit capabilities?</span>
<span class="kw">pub</span> <span class="ident">lim_uidx</span>: <span class="ident">bool</span>,
<span class="kw">pub</span> <span class="ident">lim_rmax</span>: <span class="ident">usize</span>,
<span class="kw">pub</span> <span class="ident">lim_pmax</span>: <span class="ident">usize</span>,
<span class="kw">pub</span> <span class="ident">lim_fmax</span>: <span class="ident">usize</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">UserAuthToken</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="comment">// writeln!(f, &quot;name: {}&quot;, self.name)?;</span>
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;spn: {}&quot;</span>, <span class="self">self</span>.<span class="ident">spn</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;uuid: {}&quot;</span>, <span class="self">self</span>.<span class="ident">uuid</span>)<span class="question-mark">?</span>;
<span class="comment">/*
writeln!(f, &quot;display: {}&quot;, self.displayname)?;
for group in &amp;self.groups {
writeln!(f, &quot;group: {:?}&quot;, group.name)?;
}
for claim in &amp;self.claims {
writeln!(f, &quot;claim: {:?}&quot;, claim)?;
}
*/</span>
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;token expiry: {}&quot;</span>, <span class="self">self</span>.<span class="ident">expiry</span>)
}
}
<span class="comment">// UAT will need a downcast to Entry, which adds in the claims to the entry</span>
<span class="comment">// for the purpose of filtering.</span>
<span class="comment">// This is similar to uat, but omits claims (they have no role in radius), and adds</span>
<span class="comment">// the radius secret field.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">RadiusAuthToken</span> {
<span class="kw">pub</span> <span class="ident">name</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">displayname</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">uuid</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">secret</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">groups</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Group</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">RadiusAuthToken</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;name: {}&quot;</span>, <span class="self">self</span>.<span class="ident">name</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;displayname: {}&quot;</span>, <span class="self">self</span>.<span class="ident">displayname</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;uuid: {}&quot;</span>, <span class="self">self</span>.<span class="ident">uuid</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;secret: {}&quot;</span>, <span class="self">self</span>.<span class="ident">secret</span>)<span class="question-mark">?</span>;
<span class="self">self</span>.<span class="ident">groups</span>
.<span class="ident">iter</span>()
.<span class="ident">try_for_each</span>(<span class="op">|</span><span class="ident">g</span><span class="op">|</span> <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;group: {}&quot;</span>, <span class="ident">g</span>))
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">UnixGroupToken</span> {
<span class="kw">pub</span> <span class="ident">name</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">spn</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">uuid</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">gidnumber</span>: <span class="ident">u32</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">UnixGroupToken</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;[ spn: {}, &quot;</span>, <span class="self">self</span>.<span class="ident">spn</span>)<span class="question-mark">?</span>;
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;gidnumber: {} &quot;</span>, <span class="self">self</span>.<span class="ident">gidnumber</span>)<span class="question-mark">?</span>;
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;name: {}, &quot;</span>, <span class="self">self</span>.<span class="ident">name</span>)<span class="question-mark">?</span>;
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;uuid: {} ]&quot;</span>, <span class="self">self</span>.<span class="ident">uuid</span>)
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">GroupUnixExtend</span> {
<span class="kw">pub</span> <span class="ident">gidnumber</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">u32</span><span class="op">&gt;</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">UnixUserToken</span> {
<span class="kw">pub</span> <span class="ident">name</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">spn</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">displayname</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">gidnumber</span>: <span class="ident">u32</span>,
<span class="kw">pub</span> <span class="ident">uuid</span>: <span class="ident">String</span>,
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">skip_serializing_if</span> <span class="op">=</span> <span class="string">&quot;Option::is_none&quot;</span>)]</span>
<span class="kw">pub</span> <span class="ident">shell</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">groups</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">UnixGroupToken</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">sshkeys</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="comment">// The default value of bool is false.</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">default</span>)]</span>
<span class="kw">pub</span> <span class="ident">valid</span>: <span class="ident">bool</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">UnixUserToken</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;---&quot;</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;spn: {}&quot;</span>, <span class="self">self</span>.<span class="ident">spn</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;name: {}&quot;</span>, <span class="self">self</span>.<span class="ident">name</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;displayname: {}&quot;</span>, <span class="self">self</span>.<span class="ident">displayname</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;uuid: {}&quot;</span>, <span class="self">self</span>.<span class="ident">uuid</span>)<span class="question-mark">?</span>;
<span class="kw">match</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">shell</span> {
<span class="prelude-val">Some</span>(<span class="ident">s</span>) =&gt; <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;shell: {}&quot;</span>, <span class="ident">s</span>)<span class="question-mark">?</span>,
<span class="prelude-val">None</span> =&gt; <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;shell: &lt;none&gt;&quot;</span>)<span class="question-mark">?</span>,
}
<span class="self">self</span>.<span class="ident">sshkeys</span>
.<span class="ident">iter</span>()
.<span class="ident">try_for_each</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;ssh_publickey: {}&quot;</span>, <span class="ident">s</span>))<span class="question-mark">?</span>;
<span class="self">self</span>.<span class="ident">groups</span>
.<span class="ident">iter</span>()
.<span class="ident">try_for_each</span>(<span class="op">|</span><span class="ident">g</span><span class="op">|</span> <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;group: {}&quot;</span>, <span class="ident">g</span>))
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">AccountUnixExtend</span> {
<span class="kw">pub</span> <span class="ident">gidnumber</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">u32</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">shell</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">AccountPersonSet</span> {
<span class="kw">pub</span> <span class="ident">mail</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">legalname</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
}
<span class="comment">/*
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AccountOrgPersonExtend {
pub mail: String,
}
*/</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">CredentialDetailType</span> {
<span class="ident">Password</span>,
<span class="ident">GeneratedPassword</span>,
<span class="ident">Webauthn</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>),
<span class="doccomment">/// totp, webauthn</span>
<span class="ident">PasswordMfa</span>(<span class="ident">bool</span>, <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>, <span class="ident">usize</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CredentialDetail</span> {
<span class="kw">pub</span> <span class="ident">uuid</span>: <span class="ident">Uuid</span>,
<span class="kw">pub</span> <span class="ident">claims</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">type_</span>: <span class="ident">CredentialDetailType</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">CredentialDetail</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;uuid: {}&quot;</span>, <span class="self">self</span>.<span class="ident">uuid</span>)<span class="question-mark">?</span>;
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;claims:&quot;</span>)<span class="question-mark">?</span>;
<span class="kw">for</span> <span class="ident">claim</span> <span class="kw">in</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">claims</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot; * {}&quot;</span>, <span class="ident">claim</span>)<span class="question-mark">?</span>;
}
<span class="kw">match</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">type_</span> {
<span class="ident">CredentialDetailType::Password</span> =&gt; <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;password: set&quot;</span>),
<span class="ident">CredentialDetailType::GeneratedPassword</span> =&gt; <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;generated password: set&quot;</span>),
<span class="ident">CredentialDetailType::Webauthn</span>(<span class="ident">labels</span>) =&gt; {
<span class="kw">if</span> <span class="ident">labels</span>.<span class="ident">is_empty</span>() {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;webauthn: no authenticators&quot;</span>)
} <span class="kw">else</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;webauthn:&quot;</span>)<span class="question-mark">?</span>;
<span class="kw">for</span> <span class="ident">label</span> <span class="kw">in</span> <span class="ident">labels</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot; * {}&quot;</span>, <span class="ident">label</span>)<span class="question-mark">?</span>;
}
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;&quot;</span>)
}
}
<span class="ident">CredentialDetailType::PasswordMfa</span>(<span class="ident">totp</span>, <span class="ident">labels</span>, <span class="ident">backup_code</span>) =&gt; {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;password: set&quot;</span>)<span class="question-mark">?</span>;
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">totp</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;totp: enabled&quot;</span>)<span class="question-mark">?</span>;
} <span class="kw">else</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;totp: disabled&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">backup_code</span> <span class="op">&gt;</span> <span class="number">0</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;backup_code: enabled&quot;</span>)<span class="question-mark">?</span>;
} <span class="kw">else</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;backup_code: disabled&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">if</span> <span class="ident">labels</span>.<span class="ident">is_empty</span>() {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;webauthn: no authenticators&quot;</span>)
} <span class="kw">else</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;webauthn:&quot;</span>)<span class="question-mark">?</span>;
<span class="kw">for</span> <span class="ident">label</span> <span class="kw">in</span> <span class="ident">labels</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot; * {}&quot;</span>, <span class="ident">label</span>)<span class="question-mark">?</span>;
}
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;&quot;</span>)
}
}
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CredentialStatus</span> {
<span class="kw">pub</span> <span class="ident">creds</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">CredentialDetail</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">CredentialStatus</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="kw">for</span> <span class="ident">cred</span> <span class="kw">in</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">creds</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;---&quot;</span>)<span class="question-mark">?</span>;
<span class="ident">cred</span>.<span class="ident">fmt</span>(<span class="ident">f</span>)<span class="question-mark">?</span>;
}
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;---&quot;</span>)
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">BackupCodesView</span> {
<span class="comment">// Or use SetCredentialResponse::BackupCodes?</span>
<span class="kw">pub</span> <span class="ident">backup_codes</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
}
<span class="comment">/* ===== low level proto types ===== */</span>
<span class="comment">// ProtoEntry vs Entry</span>
<span class="comment">// There is a good future reason for this seperation. It allows changing</span>
<span class="comment">// the in memory server core entry type, without affecting the protoEntry type</span>
<span class="comment">//</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>, <span class="ident">Default</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Entry</span> {
<span class="kw">pub</span> <span class="ident">attrs</span>: <span class="ident">BTreeMap</span><span class="op">&lt;</span><span class="ident">String</span>, <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">Entry</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;---&quot;</span>)<span class="question-mark">?</span>;
<span class="self">self</span>.<span class="ident">attrs</span>
.<span class="ident">iter</span>()
.<span class="ident">try_for_each</span>(<span class="op">|</span>(<span class="ident">k</span>, <span class="ident">vs</span>)<span class="op">|</span> <span class="ident">vs</span>.<span class="ident">iter</span>().<span class="ident">try_for_each</span>(<span class="op">|</span><span class="ident">v</span><span class="op">|</span> <span class="macro">writeln!</span>(<span class="ident">f</span>, <span class="string">&quot;{}: {}&quot;</span>, <span class="ident">k</span>, <span class="ident">v</span>)))
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>, <span class="ident">Ord</span>, <span class="ident">PartialOrd</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>, <span class="ident">Hash</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">Filter</span> {
<span class="comment">// This is attr - value</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">alias</span> <span class="op">=</span> <span class="string">&quot;Eq&quot;</span>)]</span>
<span class="ident">Eq</span>(<span class="ident">String</span>, <span class="ident">String</span>),
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">alias</span> <span class="op">=</span> <span class="string">&quot;Sub&quot;</span>)]</span>
<span class="ident">Sub</span>(<span class="ident">String</span>, <span class="ident">String</span>),
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">alias</span> <span class="op">=</span> <span class="string">&quot;Pres&quot;</span>)]</span>
<span class="ident">Pres</span>(<span class="ident">String</span>),
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">alias</span> <span class="op">=</span> <span class="string">&quot;Or&quot;</span>)]</span>
<span class="ident">Or</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Filter</span><span class="op">&gt;</span>),
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">alias</span> <span class="op">=</span> <span class="string">&quot;And&quot;</span>)]</span>
<span class="ident">And</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Filter</span><span class="op">&gt;</span>),
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">alias</span> <span class="op">=</span> <span class="string">&quot;AndNot&quot;</span>)]</span>
<span class="ident">AndNot</span>(<span class="ident">Box</span><span class="op">&lt;</span><span class="ident">Filter</span><span class="op">&gt;</span>),
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename</span> <span class="op">=</span> <span class="string">&quot;self&quot;</span>, <span class="ident">alias</span> <span class="op">=</span> <span class="string">&quot;Self&quot;</span>)]</span>
<span class="ident">SelfUuid</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Debug</span>, <span class="ident">Clone</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">Modify</span> {
<span class="ident">Present</span>(<span class="ident">String</span>, <span class="ident">String</span>),
<span class="ident">Removed</span>(<span class="ident">String</span>, <span class="ident">String</span>),
<span class="ident">Purged</span>(<span class="ident">String</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Debug</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">ModifyList</span> {
<span class="kw">pub</span> <span class="ident">mods</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Modify</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">ModifyList</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new_list</span>(<span class="ident">mods</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Modify</span><span class="op">&gt;</span>) -&gt; <span class="self">Self</span> {
<span class="ident">ModifyList</span> { <span class="ident">mods</span> }
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">SearchRequest</span> {
<span class="kw">pub</span> <span class="ident">filter</span>: <span class="ident">Filter</span>,
}
<span class="kw">impl</span> <span class="ident">SearchRequest</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">filter</span>: <span class="ident">Filter</span>) -&gt; <span class="self">Self</span> {
<span class="ident">SearchRequest</span> { <span class="ident">filter</span> }
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">SearchResponse</span> {
<span class="kw">pub</span> <span class="ident">entries</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Entry</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">SearchResponse</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">entries</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Entry</span><span class="op">&gt;</span>) -&gt; <span class="self">Self</span> {
<span class="ident">SearchResponse</span> { <span class="ident">entries</span> }
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CreateRequest</span> {
<span class="kw">pub</span> <span class="ident">entries</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Entry</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">CreateRequest</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">entries</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Entry</span><span class="op">&gt;</span>) -&gt; <span class="self">Self</span> {
<span class="ident">CreateRequest</span> { <span class="ident">entries</span> }
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">DeleteRequest</span> {
<span class="kw">pub</span> <span class="ident">filter</span>: <span class="ident">Filter</span>,
}
<span class="kw">impl</span> <span class="ident">DeleteRequest</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">filter</span>: <span class="ident">Filter</span>) -&gt; <span class="self">Self</span> {
<span class="ident">DeleteRequest</span> { <span class="ident">filter</span> }
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">ModifyRequest</span> {
<span class="comment">// Probably needs a modlist?</span>
<span class="kw">pub</span> <span class="ident">filter</span>: <span class="ident">Filter</span>,
<span class="kw">pub</span> <span class="ident">modlist</span>: <span class="ident">ModifyList</span>,
}
<span class="kw">impl</span> <span class="ident">ModifyRequest</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">filter</span>: <span class="ident">Filter</span>, <span class="ident">modlist</span>: <span class="ident">ModifyList</span>) -&gt; <span class="self">Self</span> {
<span class="ident">ModifyRequest</span> { <span class="ident">filter</span>, <span class="ident">modlist</span> }
}
}
<span class="comment">// Login is a multi-step process potentially. First the client says who they</span>
<span class="comment">// want to request</span>
<span class="comment">//</span>
<span class="comment">// we respond with a set of possible authentications that can proceed, and perhaps</span>
<span class="comment">// we indicate which options must/may?</span>
<span class="comment">//</span>
<span class="comment">// The client can then step and negotiate each.</span>
<span class="comment">//</span>
<span class="comment">// This continues until a LoginSuccess, or LoginFailure is returned.</span>
<span class="comment">//</span>
<span class="comment">// On loginSuccess, we send a cookie, and that allows the token to be</span>
<span class="comment">// generated. The cookie can be shared between servers.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">AuthCredential</span> {
<span class="ident">Anonymous</span>,
<span class="ident">Password</span>(<span class="ident">String</span>),
<span class="ident">Totp</span>(<span class="ident">u32</span>),
<span class="ident">Webauthn</span>(<span class="ident">PublicKeyCredential</span>),
<span class="ident">BackupCode</span>(<span class="ident">String</span>),
}
<span class="kw">impl</span> <span class="ident">fmt::Debug</span> <span class="kw">for</span> <span class="ident">AuthCredential</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">fmt</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AuthCredential::Anonymous</span> =&gt; <span class="macro">write!</span>(<span class="ident">fmt</span>, <span class="string">&quot;Anonymous&quot;</span>),
<span class="ident">AuthCredential::Password</span>(<span class="kw">_</span>) =&gt; <span class="macro">write!</span>(<span class="ident">fmt</span>, <span class="string">&quot;Password(_)&quot;</span>),
<span class="ident">AuthCredential::Totp</span>(<span class="kw">_</span>) =&gt; <span class="macro">write!</span>(<span class="ident">fmt</span>, <span class="string">&quot;TOTP(_)&quot;</span>),
<span class="ident">AuthCredential::Webauthn</span>(<span class="kw">_</span>) =&gt; <span class="macro">write!</span>(<span class="ident">fmt</span>, <span class="string">&quot;Webauthn(_)&quot;</span>),
<span class="ident">AuthCredential::BackupCode</span>(<span class="kw">_</span>) =&gt; <span class="macro">write!</span>(<span class="ident">fmt</span>, <span class="string">&quot;BackupCode(_)&quot;</span>),
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Eq</span>, <span class="ident">PartialOrd</span>, <span class="ident">Ord</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">AuthMech</span> {
<span class="ident">Anonymous</span>,
<span class="ident">Password</span>,
<span class="ident">PasswordMfa</span>,
<span class="ident">Webauthn</span>,
<span class="comment">// WebauthnVerified,</span>
<span class="comment">// PasswordWebauthnVerified</span>
}
<span class="kw">impl</span> <span class="ident">PartialEq</span> <span class="kw">for</span> <span class="ident">AuthMech</span> {
<span class="kw">fn</span> <span class="ident">eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) -&gt; <span class="ident">bool</span> {
<span class="ident">std::mem::discriminant</span>(<span class="self">self</span>) <span class="op">==</span> <span class="ident">std::mem::discriminant</span>(<span class="ident">other</span>)
}
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">AuthMech</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AuthMech::Anonymous</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;Anonymous (no credentials)&quot;</span>),
<span class="ident">AuthMech::Password</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;Passwold Only&quot;</span>),
<span class="ident">AuthMech::PasswordMfa</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;TOTP or Token, and Password&quot;</span>),
<span class="ident">AuthMech::Webauthn</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;Webauthn Token&quot;</span>),
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">AuthStep</span> {
<span class="comment">// name</span>
<span class="ident">Init</span>(<span class="ident">String</span>),
<span class="comment">// We want to talk to you like this.</span>
<span class="ident">Begin</span>(<span class="ident">AuthMech</span>),
<span class="comment">// Step</span>
<span class="ident">Cred</span>(<span class="ident">AuthCredential</span>),
<span class="comment">// Should we have a &quot;finalise&quot; type to attempt to finish based on</span>
<span class="comment">// what we have given?</span>
}
<span class="comment">// Request auth for identity X with roles Y?</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">AuthRequest</span> {
<span class="kw">pub</span> <span class="ident">step</span>: <span class="ident">AuthStep</span>,
}
<span class="comment">// Respond with the list of auth types and nonce, etc.</span>
<span class="comment">// It can also contain a denied, or success.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>, <span class="ident">Clone</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">AuthAllowed</span> {
<span class="ident">Anonymous</span>,
<span class="ident">BackupCode</span>,
<span class="ident">Password</span>,
<span class="ident">Totp</span>,
<span class="ident">Webauthn</span>(<span class="ident">RequestChallengeResponse</span>),
}
<span class="kw">impl</span> <span class="ident">PartialEq</span> <span class="kw">for</span> <span class="ident">AuthAllowed</span> {
<span class="kw">fn</span> <span class="ident">eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) -&gt; <span class="ident">bool</span> {
<span class="ident">std::mem::discriminant</span>(<span class="self">self</span>) <span class="op">==</span> <span class="ident">std::mem::discriminant</span>(<span class="ident">other</span>)
}
}
<span class="kw">impl</span> <span class="ident">Eq</span> <span class="kw">for</span> <span class="ident">AuthAllowed</span> {}
<span class="kw">impl</span> <span class="ident">Ord</span> <span class="kw">for</span> <span class="ident">AuthAllowed</span> {
<span class="kw">fn</span> <span class="ident">cmp</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) -&gt; <span class="ident">Ordering</span> {
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">eq</span>(<span class="ident">other</span>) {
<span class="ident">Ordering::Equal</span>
} <span class="kw">else</span> {
<span class="comment">// Relies on the fact that match is executed in order!</span>
<span class="kw">match</span> (<span class="self">self</span>, <span class="ident">other</span>) {
(<span class="ident">AuthAllowed::Anonymous</span>, <span class="kw">_</span>) =&gt; <span class="ident">Ordering::Less</span>,
(<span class="kw">_</span>, <span class="ident">AuthAllowed::Anonymous</span>) =&gt; <span class="ident">Ordering::Greater</span>,
(<span class="ident">AuthAllowed::Password</span>, <span class="kw">_</span>) =&gt; <span class="ident">Ordering::Less</span>,
(<span class="kw">_</span>, <span class="ident">AuthAllowed::Password</span>) =&gt; <span class="ident">Ordering::Greater</span>,
(<span class="ident">AuthAllowed::BackupCode</span>, <span class="kw">_</span>) =&gt; <span class="ident">Ordering::Less</span>,
(<span class="kw">_</span>, <span class="ident">AuthAllowed::BackupCode</span>) =&gt; <span class="ident">Ordering::Greater</span>,
(<span class="ident">AuthAllowed::Totp</span>, <span class="kw">_</span>) =&gt; <span class="ident">Ordering::Less</span>,
(<span class="kw">_</span>, <span class="ident">AuthAllowed::Totp</span>) =&gt; <span class="ident">Ordering::Greater</span>,
(<span class="ident">AuthAllowed::Webauthn</span>(<span class="kw">_</span>), <span class="kw">_</span>) =&gt; <span class="ident">Ordering::Less</span>,
<span class="comment">// Unreachable</span>
<span class="comment">// (_, AuthAllowed::Webauthn(_)) =&gt; Ordering::Greater,</span>
}
}
}
}
<span class="kw">impl</span> <span class="ident">PartialOrd</span> <span class="kw">for</span> <span class="ident">AuthAllowed</span> {
<span class="kw">fn</span> <span class="ident">partial_cmp</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) -&gt; <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Ordering</span><span class="op">&gt;</span> {
<span class="prelude-val">Some</span>(<span class="self">self</span>.<span class="ident">cmp</span>(<span class="ident">other</span>))
}
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">AuthAllowed</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AuthAllowed::Anonymous</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;Anonymous (no credentials)&quot;</span>),
<span class="ident">AuthAllowed::Password</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;Password&quot;</span>),
<span class="ident">AuthAllowed::BackupCode</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;Backup Code&quot;</span>),
<span class="ident">AuthAllowed::Totp</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;TOTP&quot;</span>),
<span class="ident">AuthAllowed::Webauthn</span>(<span class="kw">_</span>) =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;Webauthn Token&quot;</span>),
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">AuthState</span> {
<span class="comment">// You need to select how you want to talk to me.</span>
<span class="ident">Choose</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">AuthMech</span><span class="op">&gt;</span>),
<span class="comment">// Continue to auth, allowed mechanisms/challenges listed.</span>
<span class="ident">Continue</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">AuthAllowed</span><span class="op">&gt;</span>),
<span class="comment">// Something was bad, your session is terminated and no cookie.</span>
<span class="ident">Denied</span>(<span class="ident">String</span>),
<span class="comment">// Everything is good, your bearer header has been issued and is within</span>
<span class="comment">// the result.</span>
<span class="ident">Success</span>(<span class="ident">String</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">AuthResponse</span> {
<span class="kw">pub</span> <span class="ident">sessionid</span>: <span class="ident">Uuid</span>,
<span class="kw">pub</span> <span class="ident">state</span>: <span class="ident">AuthState</span>,
}
<span class="comment">// Types needed for setting credentials</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">SetCredentialRequest</span> {
<span class="ident">Password</span>(<span class="ident">String</span>),
<span class="ident">GeneratePassword</span>,
<span class="ident">TotpGenerate</span>,
<span class="ident">TotpVerify</span>(<span class="ident">Uuid</span>, <span class="ident">u32</span>),
<span class="ident">TotpAcceptSha1</span>(<span class="ident">Uuid</span>),
<span class="ident">TotpRemove</span>,
<span class="comment">// Start the rego.</span>
<span class="ident">WebauthnBegin</span>(<span class="ident">String</span>),
<span class="comment">// Finish it.</span>
<span class="ident">WebauthnRegister</span>(<span class="ident">Uuid</span>, <span class="ident">RegisterPublicKeyCredential</span>),
<span class="comment">// Remove</span>
<span class="ident">WebauthnRemove</span>(<span class="ident">String</span>),
<span class="ident">BackupCodeGenerate</span>,
<span class="ident">BackupCodeRemove</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">TotpAlgo</span> {
<span class="ident">Sha1</span>,
<span class="ident">Sha256</span>,
<span class="ident">Sha512</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">TotpAlgo</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">TotpAlgo::Sha1</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;SHA1&quot;</span>),
<span class="ident">TotpAlgo::Sha256</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;SHA256&quot;</span>),
<span class="ident">TotpAlgo::Sha512</span> =&gt; <span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;SHA512&quot;</span>),
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">TotpSecret</span> {
<span class="kw">pub</span> <span class="ident">accountname</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">issuer</span>: <span class="ident">String</span>,
<span class="kw">pub</span> <span class="ident">secret</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">u8</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">algo</span>: <span class="ident">TotpAlgo</span>,
<span class="kw">pub</span> <span class="ident">step</span>: <span class="ident">u64</span>,
}
<span class="kw">impl</span> <span class="ident">TotpSecret</span> {
<span class="doccomment">/// &lt;https://github.com/google/google-authenticator/wiki/Key-Uri-Format&gt;</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">to_uri</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">String</span> {
<span class="comment">// label = accountname / issuer (“:” / “%3A”) *”%20” accountname</span>
<span class="comment">// This is already done server side but paranoia is good!</span>
<span class="kw">let</span> <span class="ident">accountname</span> <span class="op">=</span> <span class="self">self</span>
.<span class="ident">accountname</span>
.<span class="ident">replace</span>(<span class="string">&quot;:&quot;</span>, <span class="string">&quot;&quot;</span>)
.<span class="ident">replace</span>(<span class="string">&quot;%3A&quot;</span>, <span class="string">&quot;&quot;</span>)
.<span class="ident">replace</span>(<span class="string">&quot; &quot;</span>, <span class="string">&quot;%20&quot;</span>);
<span class="kw">let</span> <span class="ident">issuer</span> <span class="op">=</span> <span class="self">self</span>
.<span class="ident">issuer</span>
.<span class="ident">replace</span>(<span class="string">&quot;:&quot;</span>, <span class="string">&quot;&quot;</span>)
.<span class="ident">replace</span>(<span class="string">&quot;%3A&quot;</span>, <span class="string">&quot;&quot;</span>)
.<span class="ident">replace</span>(<span class="string">&quot; &quot;</span>, <span class="string">&quot;%20&quot;</span>);
<span class="kw">let</span> <span class="ident">label</span> <span class="op">=</span> <span class="macro">format!</span>(<span class="string">&quot;{}:{}&quot;</span>, <span class="ident">issuer</span>, <span class="ident">accountname</span>);
<span class="kw">let</span> <span class="ident">algo</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">algo</span>.<span class="ident">to_string</span>();
<span class="kw">let</span> <span class="ident">secret</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">get_secret</span>();
<span class="kw">let</span> <span class="ident">period</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">step</span>;
<span class="macro">format!</span>(
<span class="string">&quot;otpauth://totp/{}?secret={}&amp;issuer={}&amp;algorithm={}&amp;digits=6&amp;period={}&quot;</span>,
<span class="ident">label</span>, <span class="ident">secret</span>, <span class="ident">issuer</span>, <span class="ident">algo</span>, <span class="ident">period</span>
)
}
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">get_secret</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">String</span> {
<span class="ident">base32::encode</span>(<span class="ident">base32::Alphabet::RFC4648</span> { <span class="ident">padding</span>: <span class="bool-val">false</span> }, <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">secret</span>)
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">SetCredentialResponse</span> {
<span class="ident">Success</span>,
<span class="ident">Token</span>(<span class="ident">String</span>),
<span class="ident">TotpCheck</span>(<span class="ident">Uuid</span>, <span class="ident">TotpSecret</span>),
<span class="ident">TotpInvalidSha1</span>(<span class="ident">Uuid</span>),
<span class="ident">WebauthnCreateChallenge</span>(<span class="ident">Uuid</span>, <span class="ident">CreationChallengeResponse</span>),
<span class="ident">BackupCodes</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CUIntentToken</span> {
<span class="kw">pub</span> <span class="ident">intent_token</span>: <span class="ident">String</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CUSessionToken</span> {
<span class="kw">pub</span> <span class="ident">session_token</span>: <span class="ident">String</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="attribute">#[<span class="ident">serde</span>(<span class="ident">rename_all</span> <span class="op">=</span> <span class="string">&quot;lowercase&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">CURequest</span> {
<span class="ident">PrimaryRemove</span>,
<span class="ident">Password</span>(<span class="ident">String</span>),
<span class="ident">TotpGenerate</span>,
<span class="ident">TotpVerify</span>(<span class="ident">u32</span>),
<span class="ident">TotpAcceptSha1</span>,
<span class="ident">TotpRemove</span>,
<span class="ident">BackupCodeGenerate</span>,
<span class="ident">BackupCodeRemove</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">CURegState</span> {
<span class="comment">// Nothing in progress.</span>
<span class="prelude-val">None</span>,
<span class="ident">TotpCheck</span>(<span class="ident">TotpSecret</span>),
<span class="ident">TotpTryAgain</span>,
<span class="ident">TotpInvalidSha1</span>,
<span class="ident">BackupCodes</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CUStatus</span> {
<span class="kw">pub</span> <span class="ident">can_commit</span>: <span class="ident">bool</span>,
<span class="kw">pub</span> <span class="ident">primary</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">CredentialDetail</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">mfaregstate</span>: <span class="ident">CURegState</span>,
}
<span class="comment">/* Recycle Requests area */</span>
<span class="comment">// Only two actions on recycled is possible. Search and Revive.</span>
<span class="comment">/*
pub struct SearchRecycledRequest {
pub filter: Filter,
}
impl SearchRecycledRequest {
pub fn new(filter: Filter) -&gt; Self {
SearchRecycledRequest { filter }
}
}
*/</span>
<span class="comment">// Need a search response here later.</span>
<span class="comment">/*
pub struct ReviveRecycledRequest {
pub filter: Filter,
}
impl ReviveRecycledRequest {
pub fn new(filter: Filter) -&gt; Self {
ReviveRecycledRequest { filter }
}
}
*/</span>
<span class="comment">// This doesn&#39;t need seralise because it&#39;s only accessed via a &quot;get&quot;.</span>
<span class="comment">/*
#[derive(Debug, Default)]
pub struct WhoamiRequest {}
impl WhoamiRequest {
pub fn new() -&gt; Self {
Default::default()
}
}
*/</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">WhoamiResponse</span> {
<span class="comment">// Should we just embed the entry? Or destructure it?</span>
<span class="kw">pub</span> <span class="ident">youare</span>: <span class="ident">Entry</span>,
<span class="kw">pub</span> <span class="ident">uat</span>: <span class="ident">UserAuthToken</span>,
}
<span class="kw">impl</span> <span class="ident">WhoamiResponse</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">e</span>: <span class="ident">Entry</span>, <span class="ident">uat</span>: <span class="ident">UserAuthToken</span>) -&gt; <span class="self">Self</span> {
<span class="ident">WhoamiResponse</span> { <span class="ident">youare</span>: <span class="ident">e</span>, <span class="ident">uat</span> }
}
}
<span class="comment">// Simple string value provision.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Serialize</span>, <span class="ident">Deserialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">SingleStringRequest</span> {
<span class="kw">pub</span> <span class="ident">value</span>: <span class="ident">String</span>,
}
<span class="kw">impl</span> <span class="ident">SingleStringRequest</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">s</span>: <span class="ident">String</span>) -&gt; <span class="self">Self</span> {
<span class="ident">SingleStringRequest</span> { <span class="ident">value</span>: <span class="ident">s</span> }
}
}
<span class="comment">// Use OperationResponse here ...</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"><span class="kw">crate</span>::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>::v1</span>::{<span class="ident">TotpAlgo</span>, <span class="ident">TotpSecret</span>};
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">test_protofilter_simple</span>() {
<span class="kw">let</span> <span class="ident">pf</span>: <span class="ident">ProtoFilter</span> <span class="op">=</span> <span class="ident">ProtoFilter::Pres</span>(<span class="string">&quot;class&quot;</span>.<span class="ident">to_string</span>());
<span class="macro">println!</span>(<span class="string">&quot;{:?}&quot;</span>, <span class="ident">serde_json::to_string</span>(<span class="kw-2">&amp;</span><span class="ident">pf</span>).<span class="ident">expect</span>(<span class="string">&quot;JSON failure&quot;</span>));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">totp_to_string</span>() {
<span class="kw">let</span> <span class="ident">totp</span> <span class="op">=</span> <span class="ident">TotpSecret</span> {
<span class="ident">accountname</span>: <span class="string">&quot;william&quot;</span>.<span class="ident">to_string</span>(),
<span class="ident">issuer</span>: <span class="string">&quot;blackhats&quot;</span>.<span class="ident">to_string</span>(),
<span class="ident">secret</span>: <span class="macro">vec!</span>[<span class="number">0xaa</span>, <span class="number">0xbb</span>, <span class="number">0xcc</span>, <span class="number">0xdd</span>],
<span class="ident">step</span>: <span class="number">30</span>,
<span class="ident">algo</span>: <span class="ident">TotpAlgo::Sha256</span>,
};
<span class="kw">let</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">totp</span>.<span class="ident">to_uri</span>();
<span class="macro">assert!</span>(<span class="ident">s</span> <span class="op">==</span> <span class="string">&quot;otpauth://totp/blackhats:william?secret=VK54ZXI&amp;issuer=blackhats&amp;algorithm=SHA256&amp;digits=6&amp;period=30&quot;</span>);
<span class="comment">// check that invalid issuer/accounts are cleaned up.</span>
<span class="kw">let</span> <span class="ident">totp</span> <span class="op">=</span> <span class="ident">TotpSecret</span> {
<span class="ident">accountname</span>: <span class="string">&quot;william:%3A&quot;</span>.<span class="ident">to_string</span>(),
<span class="ident">issuer</span>: <span class="string">&quot;blackhats australia&quot;</span>.<span class="ident">to_string</span>(),
<span class="ident">secret</span>: <span class="macro">vec!</span>[<span class="number">0xaa</span>, <span class="number">0xbb</span>, <span class="number">0xcc</span>, <span class="number">0xdd</span>],
<span class="ident">step</span>: <span class="number">30</span>,
<span class="ident">algo</span>: <span class="ident">TotpAlgo::Sha256</span>,
};
<span class="kw">let</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">totp</span>.<span class="ident">to_uri</span>();
<span class="macro">assert!</span>(<span class="ident">s</span> <span class="op">==</span> <span class="string">&quot;otpauth://totp/blackhats%20australia:william?secret=VK54ZXI&amp;issuer=blackhats%20australia&amp;algorithm=SHA256&amp;digits=6&amp;period=30&quot;</span>);
}
}
</code></pre></div>
</section><section id="search" class="content hidden"></section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.60.0 (7737e0b5c 2022-04-04)" ></div>
</body></html>