kanidm/docs/v1.1.0-alpha.8/rustdoc/src/kanidm_cli/account.rs.html
2022-05-06 00:07:10 +00:00

1758 lines
106 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_tools/src/cli/account.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>account.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_cli/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_cli/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_cli/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>
</pre><pre class="rust"><code><span class="kw">use</span> <span class="ident"><span class="kw">crate</span>::password_prompt</span>;
<span class="kw">use</span> <span class="kw">crate</span>::{
<span class="ident">AccountCredential</span>, <span class="ident">AccountOpt</span>, <span class="ident">AccountPerson</span>, <span class="ident">AccountPosix</span>, <span class="ident">AccountRadius</span>, <span class="ident">AccountSsh</span>,
<span class="ident">AccountValidity</span>,
};
<span class="kw">use</span> <span class="ident">qrcode</span>::{<span class="ident">render::unicode</span>, <span class="ident">QrCode</span>};
<span class="comment">// use std::io;</span>
<span class="kw">use</span> <span class="ident">kanidm_client::KanidmClient</span>;
<span class="kw">use</span> <span class="ident">time::OffsetDateTime</span>;
<span class="kw">use</span> <span class="ident">dialoguer</span>::{<span class="ident">theme::ColorfulTheme</span>, <span class="ident">Select</span>};
<span class="kw">use</span> <span class="ident">dialoguer</span>::{<span class="ident">Confirm</span>, <span class="ident">Input</span>, <span class="ident">Password</span>};
<span class="comment">// use webauthn_authenticator_rs::{u2fhid::U2FHid, WebauthnAuthenticator};</span>
<span class="comment">// use kanidm_client::ClientError;</span>
<span class="kw">use</span> <span class="ident">kanidm_client::ClientError::Http</span> <span class="kw">as</span> <span class="ident">ClientErrorHttp</span>;
<span class="kw">use</span> <span class="ident">kanidm_proto::v1::OperationError::PasswordQuality</span>;
<span class="kw">use</span> <span class="ident">kanidm_proto::v1</span>::{<span class="ident">CUIntentToken</span>, <span class="ident">CURegState</span>, <span class="ident">CUSessionToken</span>, <span class="ident">CUStatus</span>};
<span class="kw">use</span> <span class="ident">std::fmt</span>;
<span class="kw">use</span> <span class="ident">std::str::FromStr</span>;
<span class="kw">impl</span> <span class="ident">AccountOpt</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">debug</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">bool</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AccountOpt::Credential</span>(<span class="ident">acopt</span>) =&gt; <span class="ident">acopt</span>.<span class="ident">debug</span>(),
<span class="ident">AccountOpt::Radius</span>(<span class="ident">acopt</span>) =&gt; <span class="kw">match</span> <span class="ident">acopt</span> {
<span class="ident">AccountRadius::Show</span>(<span class="ident">aro</span>) =&gt; <span class="ident">aro</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountRadius::Generate</span>(<span class="ident">aro</span>) =&gt; <span class="ident">aro</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountRadius::Delete</span>(<span class="ident">aro</span>) =&gt; <span class="ident">aro</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
},
<span class="ident">AccountOpt::Posix</span>(<span class="ident">apopt</span>) =&gt; <span class="kw">match</span> <span class="ident">apopt</span> {
<span class="ident">AccountPosix::Show</span>(<span class="ident">apo</span>) =&gt; <span class="ident">apo</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountPosix::Set</span>(<span class="ident">apo</span>) =&gt; <span class="ident">apo</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountPosix::SetPassword</span>(<span class="ident">apo</span>) =&gt; <span class="ident">apo</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
},
<span class="ident">AccountOpt::Person</span>(<span class="ident">apopt</span>) =&gt; <span class="kw">match</span> <span class="ident">apopt</span> {
<span class="ident">AccountPerson::Extend</span>(<span class="ident">apo</span>) =&gt; <span class="ident">apo</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountPerson::Set</span>(<span class="ident">apo</span>) =&gt; <span class="ident">apo</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
},
<span class="ident">AccountOpt::Ssh</span>(<span class="ident">asopt</span>) =&gt; <span class="kw">match</span> <span class="ident">asopt</span> {
<span class="ident">AccountSsh::List</span>(<span class="ident">ano</span>) =&gt; <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountSsh::Add</span>(<span class="ident">ano</span>) =&gt; <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountSsh::Delete</span>(<span class="ident">ano</span>) =&gt; <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
},
<span class="ident">AccountOpt::List</span>(<span class="ident">copt</span>) =&gt; <span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountOpt::Get</span>(<span class="ident">aopt</span>) =&gt; <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountOpt::Delete</span>(<span class="ident">aopt</span>) =&gt; <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountOpt::Create</span>(<span class="ident">aopt</span>) =&gt; <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountOpt::Validity</span>(<span class="ident">avopt</span>) =&gt; <span class="kw">match</span> <span class="ident">avopt</span> {
<span class="ident">AccountValidity::Show</span>(<span class="ident">ano</span>) =&gt; <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountValidity::ExpireAt</span>(<span class="ident">ano</span>) =&gt; <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountValidity::BeginFrom</span>(<span class="ident">ano</span>) =&gt; <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
},
}
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">exec</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">match</span> <span class="self">self</span> {
<span class="comment">// id/cred/primary/set</span>
<span class="ident">AccountOpt::Credential</span>(<span class="ident">acopt</span>) =&gt; <span class="ident">acopt</span>.<span class="ident">exec</span>().<span class="kw">await</span>,
<span class="ident">AccountOpt::Radius</span>(<span class="ident">aropt</span>) =&gt; <span class="kw">match</span> <span class="ident">aropt</span> {
<span class="ident">AccountRadius::Show</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">rcred</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_radius_credential_get</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">rcred</span> {
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">s</span>)) =&gt; <span class="macro">println!</span>(<span class="string">&quot;Radius secret: {}&quot;</span>, <span class="ident">s</span>),
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>) =&gt; <span class="macro">println!</span>(<span class="string">&quot;NO Radius secret&quot;</span>),
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
<span class="ident">AccountRadius::Generate</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_radius_credential_regenerate</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
<span class="ident">AccountRadius::Delete</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_radius_credential_delete</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}, <span class="comment">// end AccountOpt::Radius</span>
<span class="ident">AccountOpt::Posix</span>(<span class="ident">apopt</span>) =&gt; <span class="kw">match</span> <span class="ident">apopt</span> {
<span class="ident">AccountPosix::Show</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_unix_token_get</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">token</span>) =&gt; <span class="macro">println!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">token</span>),
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
<span class="ident">AccountPosix::Set</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_unix_extend</span>(
<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="ident">aopt</span>.<span class="ident">gidnumber</span>,
<span class="ident">aopt</span>.<span class="ident">shell</span>.<span class="ident">as_deref</span>(),
)
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
<span class="ident">AccountPosix::SetPassword</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">password</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">password_prompt</span>(<span class="string">&quot;Enter new posix (sudo) password: &quot;</span>) {
<span class="prelude-val">Some</span>(<span class="ident">v</span>) =&gt; <span class="ident">v</span>,
<span class="prelude-val">None</span> =&gt; {
<span class="macro">println!</span>(<span class="string">&quot;Passwords do not match&quot;</span>);
<span class="kw">return</span>;
}
};
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_unix_cred_put</span>(
<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="ident">password</span>.<span class="ident">as_str</span>(),
)
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}, <span class="comment">// end AccountOpt::Posix</span>
<span class="ident">AccountOpt::Person</span>(<span class="ident">apopt</span>) =&gt; <span class="kw">match</span> <span class="ident">apopt</span> {
<span class="ident">AccountPerson::Extend</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_person_extend</span>(
<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="ident">aopt</span>.<span class="ident">mail</span>.<span class="ident">as_deref</span>(),
<span class="ident">aopt</span>.<span class="ident">legalname</span>.<span class="ident">as_deref</span>(),
)
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
<span class="ident">AccountPerson::Set</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_person_set</span>(
<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="ident">aopt</span>.<span class="ident">mail</span>.<span class="ident">as_deref</span>(),
<span class="ident">aopt</span>.<span class="ident">legalname</span>.<span class="ident">as_deref</span>(),
)
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}, <span class="comment">// end AccountOpt::Person</span>
<span class="ident">AccountOpt::Ssh</span>(<span class="ident">asopt</span>) =&gt; <span class="kw">match</span> <span class="ident">asopt</span> {
<span class="ident">AccountSsh::List</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_get_ssh_pubkeys</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">pkeys</span>) =&gt; <span class="ident">pkeys</span>.<span class="ident">iter</span>().<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">pkey</span><span class="op">|</span> <span class="macro">println!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">pkey</span>)),
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
<span class="ident">AccountSsh::Add</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_post_ssh_pubkey</span>(
<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="ident">aopt</span>.<span class="ident">tag</span>.<span class="ident">as_str</span>(),
<span class="ident">aopt</span>.<span class="ident">pubkey</span>.<span class="ident">as_str</span>(),
)
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
<span class="ident">AccountSsh::Delete</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_delete_ssh_pubkey</span>(
<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="ident">aopt</span>.<span class="ident">tag</span>.<span class="ident">as_str</span>(),
)
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}, <span class="comment">// end AccountOpt::Ssh</span>
<span class="ident">AccountOpt::List</span>(<span class="ident">copt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">client</span>.<span class="ident">idm_account_list</span>().<span class="kw">await</span> {
<span class="prelude-val">Ok</span>(<span class="ident">r</span>) =&gt; <span class="ident">r</span>.<span class="ident">iter</span>().<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">ent</span><span class="op">|</span> <span class="macro">println!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">ent</span>)),
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; <span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>),
}
}
<span class="ident">AccountOpt::Get</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">client</span>.<span class="ident">idm_account_get</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>()).<span class="kw">await</span> {
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">e</span>)) =&gt; <span class="macro">println!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">e</span>),
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>) =&gt; <span class="macro">println!</span>(<span class="string">&quot;No matching entries&quot;</span>),
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; <span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>),
}
}
<span class="ident">AccountOpt::Delete</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_delete</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>)
}
}
<span class="ident">AccountOpt::Create</span>(<span class="ident">acopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">acopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_create</span>(
<span class="ident">acopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="ident">acopt</span>.<span class="ident">display_name</span>.<span class="ident">as_str</span>(),
)
.<span class="kw">await</span>
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>)
}
}
<span class="ident">AccountOpt::Validity</span>(<span class="ident">avopt</span>) =&gt; <span class="kw">match</span> <span class="ident">avopt</span> {
<span class="ident">AccountValidity::Show</span>(<span class="ident">ano</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">ex</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_get_attr</span>(<span class="ident">ano</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(), <span class="string">&quot;account_expire&quot;</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">v</span>) =&gt; <span class="ident">v</span>,
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span>;
}
};
<span class="kw">let</span> <span class="ident">vf</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_get_attr</span>(<span class="ident">ano</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(), <span class="string">&quot;account_valid_from&quot;</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">v</span>) =&gt; <span class="ident">v</span>,
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span>;
}
};
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">t</span>) <span class="op">=</span> <span class="ident">vf</span> {
<span class="comment">// Convert the time to local timezone.</span>
<span class="kw">let</span> <span class="ident">t</span> <span class="op">=</span> <span class="ident">OffsetDateTime::parse</span>(<span class="kw-2">&amp;</span><span class="ident">t</span>[<span class="number">0</span>], <span class="ident">time::Format::Rfc3339</span>)
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">odt</span><span class="op">|</span> {
<span class="ident">odt</span>.<span class="ident">to_offset</span>(
<span class="ident">time::UtcOffset::try_current_local_offset</span>()
.<span class="ident">unwrap_or</span>(<span class="ident">time::UtcOffset::UTC</span>),
)
.<span class="ident">format</span>(<span class="ident">time::Format::Rfc3339</span>)
})
.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="string">&quot;invalid timestamp&quot;</span>.<span class="ident">to_string</span>());
<span class="macro">println!</span>(<span class="string">&quot;valid after: {}&quot;</span>, <span class="ident">t</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;valid after: any time&quot;</span>);
}
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">t</span>) <span class="op">=</span> <span class="ident">ex</span> {
<span class="kw">let</span> <span class="ident">t</span> <span class="op">=</span> <span class="ident">OffsetDateTime::parse</span>(<span class="kw-2">&amp;</span><span class="ident">t</span>[<span class="number">0</span>], <span class="ident">time::Format::Rfc3339</span>)
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">odt</span><span class="op">|</span> {
<span class="ident">odt</span>.<span class="ident">to_offset</span>(
<span class="ident">time::UtcOffset::try_current_local_offset</span>()
.<span class="ident">unwrap_or</span>(<span class="ident">time::UtcOffset::UTC</span>),
)
.<span class="ident">format</span>(<span class="ident">time::Format::Rfc3339</span>)
})
.<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="string">&quot;invalid timestamp&quot;</span>.<span class="ident">to_string</span>());
<span class="macro">println!</span>(<span class="string">&quot;expire: {}&quot;</span>, <span class="ident">t</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;expire: never&quot;</span>);
}
}
<span class="ident">AccountValidity::ExpireAt</span>(<span class="ident">ano</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="macro">matches!</span>(<span class="ident">ano</span>.<span class="ident">datetime</span>.<span class="ident">as_str</span>(), <span class="string">&quot;never&quot;</span> <span class="op">|</span> <span class="string">&quot;clear&quot;</span>) {
<span class="comment">// Unset the value</span>
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_purge_attr</span>(<span class="ident">ano</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(), <span class="string">&quot;account_expire&quot;</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; <span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>),
<span class="kw">_</span> =&gt; <span class="macro">println!</span>(<span class="string">&quot;Success&quot;</span>),
}
} <span class="kw">else</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span>
<span class="ident">OffsetDateTime::parse</span>(<span class="ident">ano</span>.<span class="ident">datetime</span>.<span class="ident">as_str</span>(), <span class="ident">time::Format::Rfc3339</span>)
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span>;
}
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_set_attr</span>(
<span class="ident">ano</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="string">&quot;account_expire&quot;</span>,
<span class="kw-2">&amp;</span>[<span class="ident">ano</span>.<span class="ident">datetime</span>.<span class="ident">as_str</span>()],
)
.<span class="kw">await</span>
{
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; <span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>),
<span class="kw">_</span> =&gt; <span class="macro">println!</span>(<span class="string">&quot;Success&quot;</span>),
}
}
}
<span class="ident">AccountValidity::BeginFrom</span>(<span class="ident">ano</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">ano</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">if</span> <span class="macro">matches!</span>(<span class="ident">ano</span>.<span class="ident">datetime</span>.<span class="ident">as_str</span>(), <span class="string">&quot;any&quot;</span> <span class="op">|</span> <span class="string">&quot;clear&quot;</span> <span class="op">|</span> <span class="string">&quot;whenever&quot;</span>) {
<span class="comment">// Unset the value</span>
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_purge_attr</span>(
<span class="ident">ano</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="string">&quot;account_valid_from&quot;</span>,
)
.<span class="kw">await</span>
{
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; <span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>),
<span class="kw">_</span> =&gt; <span class="macro">println!</span>(<span class="string">&quot;Success&quot;</span>),
}
} <span class="kw">else</span> {
<span class="comment">// Attempt to parse and set</span>
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span>
<span class="ident">OffsetDateTime::parse</span>(<span class="ident">ano</span>.<span class="ident">datetime</span>.<span class="ident">as_str</span>(), <span class="ident">time::Format::Rfc3339</span>)
{
<span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span>;
}
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_set_attr</span>(
<span class="ident">ano</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>(),
<span class="string">&quot;account_valid_from&quot;</span>,
<span class="kw-2">&amp;</span>[<span class="ident">ano</span>.<span class="ident">datetime</span>.<span class="ident">as_str</span>()],
)
.<span class="kw">await</span>
{
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; <span class="macro">error!</span>(<span class="string">&quot;Error -&gt; {:?}&quot;</span>, <span class="ident">e</span>),
<span class="kw">_</span> =&gt; <span class="macro">println!</span>(<span class="string">&quot;Success&quot;</span>),
}
}
}
}, <span class="comment">// end AccountOpt::Validity</span>
}
}
}
<span class="kw">impl</span> <span class="ident">AccountCredential</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">debug</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">bool</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AccountCredential::Update</span>(<span class="ident">aopt</span>) =&gt; <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountCredential::Reset</span>(<span class="ident">aopt</span>) =&gt; <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
<span class="ident">AccountCredential::CreateResetLink</span>(<span class="ident">aopt</span>) =&gt; <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">debug</span>,
}
}
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">exec</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AccountCredential::Update</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_begin</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">cusession_token</span>) =&gt; <span class="ident">credential_update_exec</span>(<span class="ident">cusession_token</span>, <span class="ident">client</span>).<span class="kw">await</span>,
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error starting credential update -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
<span class="ident">AccountCredential::Reset</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_unauth_client</span>();
<span class="kw">let</span> <span class="ident">cuintent_token</span> <span class="op">=</span> <span class="ident">CUIntentToken</span> {
<span class="ident">intent_token</span>: <span class="ident">aopt</span>.<span class="ident">token</span>.<span class="ident">clone</span>(),
};
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_exchange</span>(<span class="ident">cuintent_token</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">cusession_token</span>) =&gt; <span class="ident">credential_update_exec</span>(<span class="ident">cusession_token</span>, <span class="ident">client</span>).<span class="kw">await</span>,
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error starting credential reset -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
<span class="ident">AccountCredential::CreateResetLink</span>(<span class="ident">aopt</span>) =&gt; {
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">aopt</span>.<span class="ident">copt</span>.<span class="ident">to_client</span>().<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_intent</span>(<span class="ident">aopt</span>.<span class="ident">aopts</span>.<span class="ident">account_id</span>.<span class="ident">as_str</span>())
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">cuintent_token</span>) =&gt; {
<span class="macro">println!</span>(<span class="string">&quot;success!&quot;</span>);
<span class="macro">println!</span>(<span class="string">&quot;Send the person the following command&quot;</span>);
<span class="macro">println!</span>(<span class="string">&quot;&quot;</span>);
<span class="macro">println!</span>(
<span class="string">&quot;kanidm account credential reset link {}&quot;</span>,
<span class="ident">cuintent_token</span>.<span class="ident">intent_token</span>
);
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Error starting credential reset -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">enum</span> <span class="ident">CUAction</span> {
<span class="ident">Help</span>,
<span class="ident">Status</span>,
<span class="ident">Password</span>,
<span class="ident">Totp</span>,
<span class="ident">TotpRemove</span>,
<span class="ident">BackupCodes</span>,
<span class="ident">Remove</span>,
<span class="ident">End</span>,
<span class="ident">Commit</span>,
}
<span class="kw">impl</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">CUAction</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">r#&quot;
help (h, ?) - Display this help
status (ls, st) - Show the status of the credential
password (passwd, pass, pw) - Set a new password
totp - Generate a new totp, requires a password to be set
totp remove (totp rm, trm) - Remove the TOTP of this account
backup codes (bcg, bcode) - (Re)generate backup codes for this account
remove (rm) - Remove only the primary credential
end (quit, exit, x, q) - End, without saving any changes
commit (save) - Commit the changes to the credential
&quot;#</span>
)
}
}
<span class="kw">impl</span> <span class="ident">FromStr</span> <span class="kw">for</span> <span class="ident">CUAction</span> {
<span class="kw">type</span> <span class="prelude-val">Err</span> <span class="op">=</span> ();
<span class="kw">fn</span> <span class="ident">from_str</span>(<span class="ident">s</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>, <span class="ident"><span class="self">Self</span>::Err</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">s</span>.<span class="ident">to_lowercase</span>();
<span class="kw">match</span> <span class="ident">s</span>.<span class="ident">as_str</span>() {
<span class="string">&quot;help&quot;</span> <span class="op">|</span> <span class="string">&quot;h&quot;</span> <span class="op">|</span> <span class="string">&quot;?&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::Help</span>),
<span class="string">&quot;status&quot;</span> <span class="op">|</span> <span class="string">&quot;ls&quot;</span> <span class="op">|</span> <span class="string">&quot;st&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::Status</span>),
<span class="string">&quot;password&quot;</span> <span class="op">|</span> <span class="string">&quot;passwd&quot;</span> <span class="op">|</span> <span class="string">&quot;pass&quot;</span> <span class="op">|</span> <span class="string">&quot;pw&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::Password</span>),
<span class="string">&quot;totp&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::Totp</span>),
<span class="string">&quot;totp remove&quot;</span> <span class="op">|</span> <span class="string">&quot;totp rm&quot;</span> <span class="op">|</span> <span class="string">&quot;trm&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::TotpRemove</span>),
<span class="string">&quot;backup codes&quot;</span> <span class="op">|</span> <span class="string">&quot;bcode&quot;</span> <span class="op">|</span> <span class="string">&quot;bcg&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::BackupCodes</span>),
<span class="string">&quot;remove&quot;</span> <span class="op">|</span> <span class="string">&quot;rm&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::Remove</span>),
<span class="string">&quot;end&quot;</span> <span class="op">|</span> <span class="string">&quot;quit&quot;</span> <span class="op">|</span> <span class="string">&quot;exit&quot;</span> <span class="op">|</span> <span class="string">&quot;x&quot;</span> <span class="op">|</span> <span class="string">&quot;q&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::End</span>),
<span class="string">&quot;commit&quot;</span> <span class="op">|</span> <span class="string">&quot;save&quot;</span> =&gt; <span class="prelude-val">Ok</span>(<span class="ident">CUAction::Commit</span>),
<span class="kw">_</span> =&gt; <span class="prelude-val">Err</span>(()),
}
}
}
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">totp_enroll_prompt</span>(<span class="ident">session_token</span>: <span class="kw-2">&amp;</span><span class="ident">CUSessionToken</span>, <span class="ident">client</span>: <span class="kw-2">&amp;</span><span class="ident">KanidmClient</span>) {
<span class="comment">// First, submit the server side gen.</span>
<span class="kw">let</span> <span class="ident">totp_secret</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_init_totp</span>(<span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">CUStatus</span> {
<span class="ident">mfaregstate</span>: <span class="ident">CURegState::TotpCheck</span>(<span class="ident">totp_secret</span>),
..
}) =&gt; <span class="ident">totp_secret</span>,
<span class="prelude-val">Ok</span>(<span class="ident">status</span>) =&gt; {
<span class="macro">debug!</span>(<span class="question-mark">?</span><span class="ident">status</span>);
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; InvalidState&quot;</span>);
<span class="kw">return</span>;
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span>;
}
};
<span class="comment">// gen the qr</span>
<span class="macro">eprintln!</span>(<span class="string">&quot;Scan the following QR code with your OTP app.&quot;</span>);
<span class="kw">let</span> <span class="ident">code</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">QrCode::new</span>(<span class="ident">totp_secret</span>.<span class="ident">to_uri</span>().<span class="ident">as_str</span>()) {
<span class="prelude-val">Ok</span>(<span class="ident">c</span>) =&gt; <span class="ident">c</span>,
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">error!</span>(<span class="string">&quot;Failed to generate QR code -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span>;
}
};
<span class="kw">let</span> <span class="ident">image</span> <span class="op">=</span> <span class="ident">code</span>
.<span class="ident">render</span>::<span class="op">&lt;</span><span class="ident">unicode::Dense1x2</span><span class="op">&gt;</span>()
.<span class="ident">dark_color</span>(<span class="ident">unicode::Dense1x2::Light</span>)
.<span class="ident">light_color</span>(<span class="ident">unicode::Dense1x2::Dark</span>)
.<span class="ident">build</span>();
<span class="macro">eprintln!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">image</span>);
<span class="macro">eprintln!</span>(<span class="string">&quot;Alternatively, you can manually enter the following OTP details:&quot;</span>);
<span class="macro">println!</span>(<span class="string">&quot;Account Name: {}&quot;</span>, <span class="ident">totp_secret</span>.<span class="ident">accountname</span>);
<span class="macro">println!</span>(<span class="string">&quot;Issuer: {}&quot;</span>, <span class="ident">totp_secret</span>.<span class="ident">issuer</span>);
<span class="macro">println!</span>(<span class="string">&quot;Algorithm: {}&quot;</span>, <span class="ident">totp_secret</span>.<span class="ident">algo</span>);
<span class="macro">println!</span>(<span class="string">&quot;Period/Step: {}&quot;</span>, <span class="ident">totp_secret</span>.<span class="ident">step</span>);
<span class="macro">println!</span>(<span class="string">&quot;Secret: {}&quot;</span>, <span class="ident">totp_secret</span>.<span class="ident">get_secret</span>());
<span class="comment">// prompt for the totp.</span>
<span class="macro">eprintln!</span>(<span class="string">&quot;--------------------------------------------------------------&quot;</span>);
<span class="macro">eprintln!</span>(<span class="string">&quot;Enter a TOTP from your authenticator to complete registration:&quot;</span>);
<span class="comment">// Up to three attempts</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">attempts</span> <span class="op">=</span> <span class="number">3</span>;
<span class="kw">while</span> <span class="ident">attempts</span> <span class="op">&gt;</span> <span class="number">0</span> {
<span class="ident">attempts</span> <span class="op">-</span><span class="op">=</span> <span class="number">1</span>;
<span class="comment">// prompt for it. OR cancel.</span>
<span class="kw">let</span> <span class="ident">input</span>: <span class="ident">String</span> <span class="op">=</span> <span class="ident">Input::new</span>()
.<span class="ident">with_prompt</span>(<span class="string">&quot;TOTP&quot;</span>)
.<span class="ident">validate_with</span>(<span class="op">|</span><span class="ident">input</span>: <span class="kw-2">&amp;</span><span class="ident">String</span><span class="op">|</span> -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="kw-2">&amp;</span><span class="ident">str</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">input</span>.<span class="ident">to_lowercase</span>().<span class="ident">starts_with</span>(<span class="string">&#39;c&#39;</span>) <span class="op">|</span><span class="op">|</span> <span class="ident">input</span>.<span class="ident">trim</span>().<span class="ident">parse</span>::<span class="op">&lt;</span><span class="ident">u32</span><span class="op">&gt;</span>().<span class="ident">is_ok</span>() {
<span class="prelude-val">Ok</span>(())
} <span class="kw">else</span> {
<span class="prelude-val">Err</span>(<span class="string">&quot;Must be a number (123456) or cancel to end&quot;</span>)
}
})
.<span class="ident">interact_text</span>()
.<span class="ident">unwrap</span>();
<span class="comment">// cancel, submit the reg cancel.</span>
<span class="kw">let</span> <span class="ident">totp_chal</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">input</span>.<span class="ident">trim</span>().<span class="ident">parse</span>::<span class="op">&lt;</span><span class="ident">u32</span><span class="op">&gt;</span>() {
<span class="prelude-val">Ok</span>(<span class="ident">v</span>) =&gt; <span class="ident">v</span>,
<span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; {
<span class="macro">eprintln!</span>(<span class="string">&quot;Cancelling TOTP registration ...&quot;</span>);
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_cancel_mfareg</span>(<span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
}
<span class="kw">return</span>;
}
};
<span class="macro">trace!</span>(<span class="op">%</span><span class="ident">totp_chal</span>);
<span class="comment">// Submit and see what we get.</span>
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_check_totp</span>(<span class="ident">session_token</span>, <span class="ident">totp_chal</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">CUStatus</span> {
<span class="ident">mfaregstate</span>: <span class="ident">CURegState::None</span>,
..
}) =&gt; {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
<span class="kw">break</span>;
}
<span class="prelude-val">Ok</span>(<span class="ident">CUStatus</span> {
<span class="ident">mfaregstate</span>: <span class="ident">CURegState::TotpTryAgain</span>,
..
}) =&gt; {
<span class="comment">// Wrong code! Try again.</span>
<span class="macro">eprintln!</span>(<span class="string">&quot;Incorrect TOTP code entered. Please try again.&quot;</span>);
<span class="kw">continue</span>;
}
<span class="prelude-val">Ok</span>(<span class="ident">CUStatus</span> {
<span class="ident">mfaregstate</span>: <span class="ident">CURegState::TotpInvalidSha1</span>,
..
}) =&gt; {
<span class="comment">// Sha 1 warning.</span>
<span class="macro">eprintln!</span>(<span class="string">&quot;⚠️ WARNING - It appears your authenticator app may be broken ⚠️ &quot;</span>);
<span class="macro">eprintln!</span>(<span class="string">&quot; The TOTP authenticator you are using is forcing the use of SHA1\n&quot;</span>);
<span class="macro">eprintln!</span>(
<span class="string">&quot; SHA1 is a deprecated and potentially insecure cryptographic algorithm\n&quot;</span>
);
<span class="kw">let</span> <span class="ident">items</span> <span class="op">=</span> <span class="macro">vec!</span>[<span class="string">&quot;Cancel&quot;</span>, <span class="string">&quot;I am sure&quot;</span>];
<span class="kw">let</span> <span class="ident">selection</span> <span class="op">=</span> <span class="ident">Select::with_theme</span>(<span class="kw-2">&amp;</span><span class="ident">ColorfulTheme::default</span>())
.<span class="ident">items</span>(<span class="kw-2">&amp;</span><span class="ident">items</span>)
.<span class="ident">default</span>(<span class="number">0</span>)
.<span class="ident">interact</span>()
.<span class="ident">unwrap</span>();
<span class="kw">match</span> <span class="ident">selection</span> {
<span class="number">1</span> =&gt; {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_accept_sha1_totp</span>(<span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
}
}
<span class="kw">_</span> =&gt; {
<span class="macro">println!</span>(<span class="string">&quot;Cancelling TOTP registration ...&quot;</span>);
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_cancel_mfareg</span>(<span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
}
}
}
<span class="kw">return</span>;
}
<span class="prelude-val">Ok</span>(<span class="ident">status</span>) =&gt; {
<span class="macro">debug!</span>(<span class="question-mark">?</span><span class="ident">status</span>);
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; InvalidState&quot;</span>);
<span class="kw">return</span>;
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span>;
}
}
}
<span class="comment">// Done!</span>
}
<span class="comment">// For webauthn later</span>
<span class="comment">/*
AccountCredential::RegisterWebauthn(acsopt) =&gt; {
let client = acsopt.copt.to_client().await;
let (session, chal) = match client
.idm_account_primary_credential_register_webauthn(
acsopt.aopts.account_id.as_str(),
acsopt.tag.as_str(),
)
.await
{
Ok(v) =&gt; v,
Err(e) =&gt; {
error!(&quot;Error Starting Registration -&gt; {:?}&quot;, e);
return;
}
};
let mut wa = WebauthnAuthenticator::new(U2FHid::new());
eprintln!(&quot;Your authenticator will now flash for you to interact with.&quot;);
let rego = match wa.do_registration(client.get_origin(), chal) {
Ok(rego) =&gt; rego,
Err(e) =&gt; {
error!(&quot;Error Signing -&gt; {:?}&quot;, e);
return;
}
};
match client
.idm_account_primary_credential_complete_webuthn_registration(
acsopt.aopts.account_id.as_str(),
rego,
session,
)
.await
{
Ok(()) =&gt; {
println!(&quot;Webauthn token registration success.&quot;);
}
Err(e) =&gt; {
error!(&quot;Error Completing -&gt; {:?}&quot;, e);
}
}
}
*/</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">credential_update_exec</span>(<span class="ident">session_token</span>: <span class="ident">CUSessionToken</span>, <span class="ident">client</span>: <span class="ident">KanidmClient</span>) {
<span class="macro">trace!</span>(<span class="string">&quot;started credential update exec&quot;</span>);
<span class="kw">loop</span> {
<span class="comment">// Display Prompt</span>
<span class="kw">let</span> <span class="ident">input</span>: <span class="ident">String</span> <span class="op">=</span> <span class="ident">Input::new</span>()
.<span class="ident">with_prompt</span>(<span class="string">&quot;\ncred update (? for help) # &quot;</span>)
.<span class="ident">validate_with</span>(<span class="op">|</span><span class="ident">input</span>: <span class="kw-2">&amp;</span><span class="ident">String</span><span class="op">|</span> -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="kw-2">&amp;</span><span class="ident">str</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">CUAction::from_str</span>(<span class="ident">input</span>).<span class="ident">is_ok</span>() {
<span class="prelude-val">Ok</span>(())
} <span class="kw">else</span> {
<span class="prelude-val">Err</span>(<span class="string">&quot;This is not a valid command. See help for valid options (?)&quot;</span>)
}
})
.<span class="ident">interact_text</span>()
.<span class="ident">unwrap</span>();
<span class="comment">// Get action</span>
<span class="kw">let</span> <span class="ident">action</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">CUAction::from_str</span>(<span class="kw-2">&amp;</span><span class="ident">input</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">a</span>) =&gt; <span class="ident">a</span>,
<span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; <span class="kw">continue</span>,
};
<span class="macro">trace!</span>(<span class="question-mark">?</span><span class="ident">action</span>);
<span class="kw">match</span> <span class="ident">action</span> {
<span class="ident">CUAction::Help</span> =&gt; {
<span class="macro">print!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">action</span>);
}
<span class="ident">CUAction::Status</span> =&gt; {
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_status</span>(<span class="kw-2">&amp;</span><span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">status</span>) =&gt; {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">cred_detail</span>) <span class="op">=</span> <span class="ident">status</span>.<span class="ident">primary</span> {
<span class="macro">println!</span>(<span class="string">&quot;Primary Credential:&quot;</span>);
<span class="macro">print!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">cred_detail</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;Primary Credential:&quot;</span>);
<span class="macro">println!</span>(<span class="string">&quot; not set&quot;</span>);
}
<span class="comment">// We may need to be able to display if there are dangling</span>
<span class="comment">// curegstates, but the cli ui statemachine can match the</span>
<span class="comment">// server so it may not be needed?</span>
<span class="macro">println!</span>(<span class="string">&quot;Can Commit: {}&quot;</span>, <span class="ident">status</span>.<span class="ident">can_commit</span>);
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
<span class="ident">CUAction::Password</span> =&gt; {
<span class="kw">let</span> <span class="ident">password_a</span> <span class="op">=</span> <span class="ident">Password::new</span>()
.<span class="ident">with_prompt</span>(<span class="string">&quot;New password&quot;</span>)
.<span class="ident">interact</span>()
.<span class="ident">unwrap</span>();
<span class="kw">let</span> <span class="ident">password_b</span> <span class="op">=</span> <span class="ident">Password::new</span>()
.<span class="ident">with_prompt</span>(<span class="string">&quot;Confirm password&quot;</span>)
.<span class="ident">interact</span>()
.<span class="ident">unwrap</span>();
<span class="kw">if</span> <span class="ident">password_a</span> <span class="op">!</span><span class="op">=</span> <span class="ident">password_b</span> {
<span class="macro">eprintln!</span>(<span class="string">&quot;Passwords do not match&quot;</span>);
} <span class="kw">else</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_set_password</span>(<span class="kw-2">&amp;</span><span class="ident">session_token</span>, <span class="kw-2">&amp;</span><span class="ident">password_a</span>)
.<span class="kw">await</span>
{
<span class="kw">match</span> <span class="ident">e</span> {
<span class="ident">ClientErrorHttp</span>(<span class="kw">_</span>, <span class="prelude-val">Some</span>(<span class="ident">PasswordQuality</span>(<span class="ident">feedback</span>)), <span class="kw">_</span>) =&gt; {
<span class="kw">for</span> <span class="ident">fb_item</span> <span class="kw">in</span> <span class="ident">feedback</span>.<span class="ident">iter</span>() {
<span class="macro">eprintln!</span>(<span class="string">&quot;{:?}&quot;</span>, <span class="ident">fb_item</span>)
}
}
<span class="kw">_</span> =&gt; <span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>),
}
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
}
}
}
<span class="ident">CUAction::Totp</span> =&gt; <span class="ident">totp_enroll_prompt</span>(<span class="kw-2">&amp;</span><span class="ident">session_token</span>, <span class="kw-2">&amp;</span><span class="ident">client</span>).<span class="kw">await</span>,
<span class="ident">CUAction::TotpRemove</span> =&gt; {
<span class="kw">if</span> <span class="ident">Confirm::new</span>()
.<span class="ident">with_prompt</span>(<span class="string">&quot;Do you want to remove your totp?&quot;</span>)
.<span class="ident">interact</span>()
.<span class="ident">unwrap</span>()
{
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_remove_totp</span>(<span class="kw-2">&amp;</span><span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
}
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;Totp was NOT removed&quot;</span>);
}
}
<span class="ident">CUAction::BackupCodes</span> =&gt; {
<span class="kw">match</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_backup_codes_generate</span>(<span class="kw-2">&amp;</span><span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="prelude-val">Ok</span>(<span class="ident">CUStatus</span> {
<span class="ident">mfaregstate</span>: <span class="ident">CURegState::BackupCodes</span>(<span class="ident">codes</span>),
..
}) =&gt; {
<span class="macro">println!</span>(<span class="string">&quot;Please store these Backup codes in a safe place&quot;</span>);
<span class="macro">println!</span>(<span class="string">&quot;They will only be displayed ONCE&quot;</span>);
<span class="kw">for</span> <span class="ident">code</span> <span class="kw">in</span> <span class="ident">codes</span> {
<span class="macro">println!</span>(<span class="string">&quot; {}&quot;</span>, <span class="ident">code</span>)
}
}
<span class="prelude-val">Ok</span>(<span class="ident">status</span>) =&gt; {
<span class="macro">debug!</span>(<span class="question-mark">?</span><span class="ident">status</span>);
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; InvalidState&quot;</span>);
}
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; {
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
}
}
}
<span class="ident">CUAction::Remove</span> =&gt; {
<span class="kw">if</span> <span class="ident">Confirm::new</span>()
.<span class="ident">with_prompt</span>(<span class="string">&quot;Do you want to remove your primary credential?&quot;</span>)
.<span class="ident">interact</span>()
.<span class="ident">unwrap</span>()
{
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_primary_remove</span>(<span class="kw-2">&amp;</span><span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
}
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;Primary credential was NOT removed&quot;</span>);
}
}
<span class="ident">CUAction::End</span> =&gt; {
<span class="macro">println!</span>(<span class="string">&quot;Changes were NOT saved.&quot;</span>);
<span class="kw">break</span>;
}
<span class="ident">CUAction::Commit</span> =&gt; {
<span class="kw">if</span> <span class="ident">Confirm::new</span>()
.<span class="ident">with_prompt</span>(<span class="string">&quot;Do you want to commit your changes?&quot;</span>)
.<span class="ident">interact</span>()
.<span class="ident">unwrap</span>()
{
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">idm_account_credential_update_commit</span>(<span class="kw-2">&amp;</span><span class="ident">session_token</span>)
.<span class="kw">await</span>
{
<span class="macro">eprintln!</span>(<span class="string">&quot;An error occured -&gt; {:?}&quot;</span>, <span class="ident">e</span>);
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;success&quot;</span>);
}
<span class="kw">break</span>;
} <span class="kw">else</span> {
<span class="macro">println!</span>(<span class="string">&quot;Changes have NOT been saved.&quot;</span>);
}
}
}
}
<span class="macro">trace!</span>(<span class="string">&quot;ended credential update exec&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_cli" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.60.0 (7737e0b5c 2022-04-04)" ></div>
</body></html>