mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
deploy: f344c68159
This commit is contained in:
parent
fc5bd95d30
commit
9076f72804
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3682">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3901">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<p>This contains the in memory and loaded set of active oauth2 resource server
|
||||
integrations, which are then able to be used an accessed from the IDM layer
|
||||
for operations involving oauth2 authentication processing.</p>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
<!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="API documentation for the Rust `setup_async_test` fn in crate `kanidmd_testkit`."><meta name="keywords" content="rust, rustlang, rust-lang, setup_async_test"><title>setup_async_test in kanidmd_testkit - Rust</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" href="../normalize.css"><link rel="stylesheet" href="../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../ayu.css" disabled><link rel="stylesheet" href="../dark.css" disabled><link rel="stylesheet" href="../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../storage.js"></script><script defer src="sidebar-items.js"></script><script defer src="../main.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../favicon.svg"></head><body class="rustdoc fn"><!--[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">☰</button><a class="sidebar-logo" href="../kanidmd_testkit/index.html"><div class="logo-container"><img class="rust-logo" src="../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../kanidmd_testkit/index.html"><div class="logo-container"><img class="rust-logo" src="../rust-logo.svg" alt="logo"></div></a><div class="sidebar-elems"><h2><a href="index.html">In kanidmd_testkit</a></h2></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Function <a href="index.html">kanidmd_testkit</a>::<wbr><a class="fn" href="#">setup_async_test</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../src/kanidmd_testkit/lib.rs.html#39-89">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><div class="item-decl"><pre class="rust fn"><code>pub async fn setup_async_test() -> (<a class="struct" href="../kanidm_client/struct.KanidmClient.html" title="struct kanidm_client::KanidmClient">KanidmClient</a>, CoreHandle)</code></pre></div></section></div></main><div id="rustdoc-vars" data-root-path="../" data-current-crate="kanidmd_testkit" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="API documentation for the Rust `setup_async_test` fn in crate `kanidmd_testkit`."><meta name="keywords" content="rust, rustlang, rust-lang, setup_async_test"><title>setup_async_test in kanidmd_testkit - Rust</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" href="../normalize.css"><link rel="stylesheet" href="../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../ayu.css" disabled><link rel="stylesheet" href="../dark.css" disabled><link rel="stylesheet" href="../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../storage.js"></script><script defer src="sidebar-items.js"></script><script defer src="../main.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../favicon.svg"></head><body class="rustdoc fn"><!--[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">☰</button><a class="sidebar-logo" href="../kanidmd_testkit/index.html"><div class="logo-container"><img class="rust-logo" src="../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../kanidmd_testkit/index.html"><div class="logo-container"><img class="rust-logo" src="../rust-logo.svg" alt="logo"></div></a><div class="sidebar-elems"><h2><a href="index.html">In kanidmd_testkit</a></h2></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Function <a href="index.html">kanidmd_testkit</a>::<wbr><a class="fn" href="#">setup_async_test</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../src/kanidmd_testkit/lib.rs.html#39-89">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><div class="item-decl"><pre class="rust fn"><code>pub async fn setup_async_test() -> (KanidmClient, CoreHandle)</code></pre></div></section></div></main><div id="rustdoc-vars" data-root-path="../" data-current-crate="kanidmd_testkit" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
File diff suppressed because one or more lines are too long
|
@ -938,7 +938,7 @@
|
|||
<span class="attribute">#[instrument(level = <span class="string">"trace"</span>, skip_all)]
|
||||
</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>try_from_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, OperationError> {
|
||||
<span class="kw">let </span>groups = Group::try_from_account_entry_ro(value, qs)<span class="question-mark">?</span>;
|
||||
<span class="macro">try_from_entry!</span>(value, groups)
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>try_from_account_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><Vec<<span class="self">Self</span>>, OperationError> {
|
||||
<span class="macro">try_from_account_e!</span>(value, qs)
|
||||
}
|
||||
|
|
|
@ -3680,6 +3680,225 @@
|
|||
<span id="3680">3680</span>
|
||||
<span id="3681">3681</span>
|
||||
<span id="3682">3682</span>
|
||||
<span id="3683">3683</span>
|
||||
<span id="3684">3684</span>
|
||||
<span id="3685">3685</span>
|
||||
<span id="3686">3686</span>
|
||||
<span id="3687">3687</span>
|
||||
<span id="3688">3688</span>
|
||||
<span id="3689">3689</span>
|
||||
<span id="3690">3690</span>
|
||||
<span id="3691">3691</span>
|
||||
<span id="3692">3692</span>
|
||||
<span id="3693">3693</span>
|
||||
<span id="3694">3694</span>
|
||||
<span id="3695">3695</span>
|
||||
<span id="3696">3696</span>
|
||||
<span id="3697">3697</span>
|
||||
<span id="3698">3698</span>
|
||||
<span id="3699">3699</span>
|
||||
<span id="3700">3700</span>
|
||||
<span id="3701">3701</span>
|
||||
<span id="3702">3702</span>
|
||||
<span id="3703">3703</span>
|
||||
<span id="3704">3704</span>
|
||||
<span id="3705">3705</span>
|
||||
<span id="3706">3706</span>
|
||||
<span id="3707">3707</span>
|
||||
<span id="3708">3708</span>
|
||||
<span id="3709">3709</span>
|
||||
<span id="3710">3710</span>
|
||||
<span id="3711">3711</span>
|
||||
<span id="3712">3712</span>
|
||||
<span id="3713">3713</span>
|
||||
<span id="3714">3714</span>
|
||||
<span id="3715">3715</span>
|
||||
<span id="3716">3716</span>
|
||||
<span id="3717">3717</span>
|
||||
<span id="3718">3718</span>
|
||||
<span id="3719">3719</span>
|
||||
<span id="3720">3720</span>
|
||||
<span id="3721">3721</span>
|
||||
<span id="3722">3722</span>
|
||||
<span id="3723">3723</span>
|
||||
<span id="3724">3724</span>
|
||||
<span id="3725">3725</span>
|
||||
<span id="3726">3726</span>
|
||||
<span id="3727">3727</span>
|
||||
<span id="3728">3728</span>
|
||||
<span id="3729">3729</span>
|
||||
<span id="3730">3730</span>
|
||||
<span id="3731">3731</span>
|
||||
<span id="3732">3732</span>
|
||||
<span id="3733">3733</span>
|
||||
<span id="3734">3734</span>
|
||||
<span id="3735">3735</span>
|
||||
<span id="3736">3736</span>
|
||||
<span id="3737">3737</span>
|
||||
<span id="3738">3738</span>
|
||||
<span id="3739">3739</span>
|
||||
<span id="3740">3740</span>
|
||||
<span id="3741">3741</span>
|
||||
<span id="3742">3742</span>
|
||||
<span id="3743">3743</span>
|
||||
<span id="3744">3744</span>
|
||||
<span id="3745">3745</span>
|
||||
<span id="3746">3746</span>
|
||||
<span id="3747">3747</span>
|
||||
<span id="3748">3748</span>
|
||||
<span id="3749">3749</span>
|
||||
<span id="3750">3750</span>
|
||||
<span id="3751">3751</span>
|
||||
<span id="3752">3752</span>
|
||||
<span id="3753">3753</span>
|
||||
<span id="3754">3754</span>
|
||||
<span id="3755">3755</span>
|
||||
<span id="3756">3756</span>
|
||||
<span id="3757">3757</span>
|
||||
<span id="3758">3758</span>
|
||||
<span id="3759">3759</span>
|
||||
<span id="3760">3760</span>
|
||||
<span id="3761">3761</span>
|
||||
<span id="3762">3762</span>
|
||||
<span id="3763">3763</span>
|
||||
<span id="3764">3764</span>
|
||||
<span id="3765">3765</span>
|
||||
<span id="3766">3766</span>
|
||||
<span id="3767">3767</span>
|
||||
<span id="3768">3768</span>
|
||||
<span id="3769">3769</span>
|
||||
<span id="3770">3770</span>
|
||||
<span id="3771">3771</span>
|
||||
<span id="3772">3772</span>
|
||||
<span id="3773">3773</span>
|
||||
<span id="3774">3774</span>
|
||||
<span id="3775">3775</span>
|
||||
<span id="3776">3776</span>
|
||||
<span id="3777">3777</span>
|
||||
<span id="3778">3778</span>
|
||||
<span id="3779">3779</span>
|
||||
<span id="3780">3780</span>
|
||||
<span id="3781">3781</span>
|
||||
<span id="3782">3782</span>
|
||||
<span id="3783">3783</span>
|
||||
<span id="3784">3784</span>
|
||||
<span id="3785">3785</span>
|
||||
<span id="3786">3786</span>
|
||||
<span id="3787">3787</span>
|
||||
<span id="3788">3788</span>
|
||||
<span id="3789">3789</span>
|
||||
<span id="3790">3790</span>
|
||||
<span id="3791">3791</span>
|
||||
<span id="3792">3792</span>
|
||||
<span id="3793">3793</span>
|
||||
<span id="3794">3794</span>
|
||||
<span id="3795">3795</span>
|
||||
<span id="3796">3796</span>
|
||||
<span id="3797">3797</span>
|
||||
<span id="3798">3798</span>
|
||||
<span id="3799">3799</span>
|
||||
<span id="3800">3800</span>
|
||||
<span id="3801">3801</span>
|
||||
<span id="3802">3802</span>
|
||||
<span id="3803">3803</span>
|
||||
<span id="3804">3804</span>
|
||||
<span id="3805">3805</span>
|
||||
<span id="3806">3806</span>
|
||||
<span id="3807">3807</span>
|
||||
<span id="3808">3808</span>
|
||||
<span id="3809">3809</span>
|
||||
<span id="3810">3810</span>
|
||||
<span id="3811">3811</span>
|
||||
<span id="3812">3812</span>
|
||||
<span id="3813">3813</span>
|
||||
<span id="3814">3814</span>
|
||||
<span id="3815">3815</span>
|
||||
<span id="3816">3816</span>
|
||||
<span id="3817">3817</span>
|
||||
<span id="3818">3818</span>
|
||||
<span id="3819">3819</span>
|
||||
<span id="3820">3820</span>
|
||||
<span id="3821">3821</span>
|
||||
<span id="3822">3822</span>
|
||||
<span id="3823">3823</span>
|
||||
<span id="3824">3824</span>
|
||||
<span id="3825">3825</span>
|
||||
<span id="3826">3826</span>
|
||||
<span id="3827">3827</span>
|
||||
<span id="3828">3828</span>
|
||||
<span id="3829">3829</span>
|
||||
<span id="3830">3830</span>
|
||||
<span id="3831">3831</span>
|
||||
<span id="3832">3832</span>
|
||||
<span id="3833">3833</span>
|
||||
<span id="3834">3834</span>
|
||||
<span id="3835">3835</span>
|
||||
<span id="3836">3836</span>
|
||||
<span id="3837">3837</span>
|
||||
<span id="3838">3838</span>
|
||||
<span id="3839">3839</span>
|
||||
<span id="3840">3840</span>
|
||||
<span id="3841">3841</span>
|
||||
<span id="3842">3842</span>
|
||||
<span id="3843">3843</span>
|
||||
<span id="3844">3844</span>
|
||||
<span id="3845">3845</span>
|
||||
<span id="3846">3846</span>
|
||||
<span id="3847">3847</span>
|
||||
<span id="3848">3848</span>
|
||||
<span id="3849">3849</span>
|
||||
<span id="3850">3850</span>
|
||||
<span id="3851">3851</span>
|
||||
<span id="3852">3852</span>
|
||||
<span id="3853">3853</span>
|
||||
<span id="3854">3854</span>
|
||||
<span id="3855">3855</span>
|
||||
<span id="3856">3856</span>
|
||||
<span id="3857">3857</span>
|
||||
<span id="3858">3858</span>
|
||||
<span id="3859">3859</span>
|
||||
<span id="3860">3860</span>
|
||||
<span id="3861">3861</span>
|
||||
<span id="3862">3862</span>
|
||||
<span id="3863">3863</span>
|
||||
<span id="3864">3864</span>
|
||||
<span id="3865">3865</span>
|
||||
<span id="3866">3866</span>
|
||||
<span id="3867">3867</span>
|
||||
<span id="3868">3868</span>
|
||||
<span id="3869">3869</span>
|
||||
<span id="3870">3870</span>
|
||||
<span id="3871">3871</span>
|
||||
<span id="3872">3872</span>
|
||||
<span id="3873">3873</span>
|
||||
<span id="3874">3874</span>
|
||||
<span id="3875">3875</span>
|
||||
<span id="3876">3876</span>
|
||||
<span id="3877">3877</span>
|
||||
<span id="3878">3878</span>
|
||||
<span id="3879">3879</span>
|
||||
<span id="3880">3880</span>
|
||||
<span id="3881">3881</span>
|
||||
<span id="3882">3882</span>
|
||||
<span id="3883">3883</span>
|
||||
<span id="3884">3884</span>
|
||||
<span id="3885">3885</span>
|
||||
<span id="3886">3886</span>
|
||||
<span id="3887">3887</span>
|
||||
<span id="3888">3888</span>
|
||||
<span id="3889">3889</span>
|
||||
<span id="3890">3890</span>
|
||||
<span id="3891">3891</span>
|
||||
<span id="3892">3892</span>
|
||||
<span id="3893">3893</span>
|
||||
<span id="3894">3894</span>
|
||||
<span id="3895">3895</span>
|
||||
<span id="3896">3896</span>
|
||||
<span id="3897">3897</span>
|
||||
<span id="3898">3898</span>
|
||||
<span id="3899">3899</span>
|
||||
<span id="3900">3900</span>
|
||||
<span id="3901">3901</span>
|
||||
</pre><pre class="rust"><code><span class="doccomment">//! Oauth2 resource server configurations
|
||||
//!
|
||||
//! This contains the in memory and loaded set of active oauth2 resource server
|
||||
|
@ -3716,6 +3935,7 @@
|
|||
<span class="kw">use </span>url::{Origin, Url};
|
||||
|
||||
<span class="kw">use </span><span class="kw">crate</span>::identity::IdentityId;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::account::Account;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::delayed::{DelayedAction, Oauth2ConsentGrant, Oauth2SessionRecord};
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::server::{
|
||||
IdmServerProxyReadTransaction, IdmServerProxyWriteTransaction, IdmServerTransaction,
|
||||
|
@ -4637,6 +4857,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_exchange(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
client_authz: <span class="prelude-ty">Option</span><<span class="kw-2">&</span>str>,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4673,7 +4894,7 @@
|
|||
// TODO: add refresh token grant type.
|
||||
// If it's a refresh token grant, are the consent permissions the same?
|
||||
</span><span class="kw">if </span>token_req.grant_type == <span class="string">"authorization_code" </span>{
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(o2rs, token_req, ct, async_tx)
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(idms, o2rs, token_req, ct, async_tx)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">admin_warn!</span>(<span class="string">"Invalid oauth2 grant_type (should be 'authorization_code')"</span>);
|
||||
<span class="prelude-val">Err</span>(Oauth2Error::InvalidRequest)
|
||||
|
@ -4682,6 +4903,7 @@
|
|||
|
||||
<span class="kw">fn </span>check_oauth2_token_exchange_authorization_code(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
o2rs: <span class="kw-2">&</span>Oauth2RS,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4776,9 +4998,7 @@
|
|||
<span class="prelude-val">Some</span>(code_xchg.scopes.join(<span class="string">" "</span>))
|
||||
};
|
||||
|
||||
<span class="kw">let </span>scope_set: BTreeSet<String> = code_xchg.scopes.iter().cloned().collect();
|
||||
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>scope_set.contains(<span class="string">"openid"</span>) {
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>code_xchg.scopes.contains(<span class="kw-2">&</span><span class="string">"openid"</span>.to_string()) {
|
||||
<span class="comment">// TODO: Scopes map to claims:
|
||||
//
|
||||
// * profile - (name, family\_name, given\_name, middle\_name, nickname, preferred\_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
|
@ -4791,24 +5011,7 @@
|
|||
// TODO: Can the user consent to which claims are released? Today as we don't support most
|
||||
// of them anyway, no, but in the future, we can stash these to the consent req.
|
||||
|
||||
</span><span class="macro">admin_warn!</span>(<span class="string">"prefer_short_username: {:?}"</span>, o2rs.prefer_short_username);
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.name().to_string())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scope_set.contains(<span class="string">"email"</span>) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = code_xchg.uat.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
<span class="comment">// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
|
||||
// amr == auth method
|
||||
</span><span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[code_xchg.uat.auth_type.to_string()]);
|
||||
|
@ -4818,6 +5021,19 @@
|
|||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>idms.qs_read.internal_search_uuid(code_xchg.uat.uuid) {
|
||||
<span class="prelude-val">Ok</span>(entry) => entry,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
|
||||
<span class="kw">let </span>oidc = OidcToken {
|
||||
iss,
|
||||
sub: OidcSubject::U(code_xchg.uat.uuid),
|
||||
|
@ -4832,17 +5048,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(o2rs.name.clone()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(code_xchg.uat.displayname.clone()),
|
||||
<span class="comment">// Map from spn
|
||||
</span>scopes: code_xchg.scopes.clone(),
|
||||
email,
|
||||
email_verified,
|
||||
preferred_username,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
};
|
||||
|
||||
<span class="macro">trace!</span>(<span class="question-mark">?</span>oidc);
|
||||
|
@ -4972,17 +5179,22 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
<span class="string">"access token has account not valid, returning inactive"
|
||||
<span class="string">"access token has no account not valid, returning inactive"
|
||||
</span>);
|
||||
<span class="kw">return </span><span class="prelude-val">Ok</span>(AccessTokenIntrospectResponse::inactive());
|
||||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_no_groups(<span class="kw-2">&</span>entry) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="kw">let </span>scope = <span class="kw">if </span>scopes.is_empty() {
|
||||
|
@ -5064,8 +5276,8 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
|
@ -5075,26 +5287,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn)
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[auth_type.to_string()]);
|
||||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="prelude-val">Ok</span>(OidcToken {
|
||||
|
@ -5111,16 +5315,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(client_id.to_string()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes,
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
})
|
||||
}
|
||||
<span class="comment">// https://openid.net/specs/openid-connect-basic-1_0.html#UserInfoErrorResponse
|
||||
|
@ -5259,6 +5455,47 @@
|
|||
<span class="prelude-val">Ok</span>((client_id.to_string(), secret.to_string()))
|
||||
}
|
||||
|
||||
<span class="kw">fn </span>s_claims_for_account(o2rs: <span class="kw-2">&</span>Oauth2RS, account: <span class="kw-2">&</span>Account, scopes: <span class="kw-2">&</span>[String]) -> OidcClaims {
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name.clone())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = <span class="kw-2">&</span>account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp.clone()), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes: scopes.to_vec(),
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
<span class="kw">fn </span>extra_claims_for_account(
|
||||
account: <span class="kw-2">&</span>Account,
|
||||
scopes: <span class="kw-2">&</span>[String],
|
||||
) -> BTreeMap<String, serde_json::Value> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>extra_claims = BTreeMap::new();
|
||||
<span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()) {
|
||||
extra_claims.insert(
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
account.groups.iter().map(|x| x.to_proto().uuid).collect(),
|
||||
);
|
||||
}
|
||||
<span class="kw">return </span>extra_claims;
|
||||
}
|
||||
|
||||
<span class="attribute">#[cfg(test)]
|
||||
</span><span class="kw">mod </span>tests {
|
||||
<span class="kw">use </span>std::convert::TryFrom;
|
||||
|
@ -5299,7 +5536,8 @@
|
|||
<span class="macro-nonterminal">$ident</span>:expr,
|
||||
<span class="macro-nonterminal">$uat</span>:expr,
|
||||
<span class="macro-nonterminal">$ct</span>:expr,
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr,
|
||||
<span class="macro-nonterminal">$scope</span>:expr
|
||||
) => {{
|
||||
<span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
response_type: <span class="string">"code"</span>.to_string(),
|
||||
|
@ -5310,7 +5548,7 @@
|
|||
code_challenge_method: CodeChallengeMethod::S256,
|
||||
}),
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
scope: <span class="string">"openid"</span>.to_string(),
|
||||
scope: <span class="macro-nonterminal">$scope</span>,
|
||||
nonce: <span class="prelude-val">Some</span>(<span class="string">"abcdef"</span>.to_string()),
|
||||
oidc_ext: Default::default(),
|
||||
unknown_keys: Default::default(),
|
||||
|
@ -5348,7 +5586,7 @@
|
|||
<span class="comment">// System admins
|
||||
</span>(
|
||||
<span class="string">"oauth2_rs_scope_map"</span>,
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"read"</span>.to_string()])
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"groups"</span>.to_string()])
|
||||
.expect(<span class="string">"invalid oauthscope"</span>)
|
||||
),
|
||||
(
|
||||
|
@ -5448,8 +5686,14 @@
|
|||
// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -5702,8 +5946,14 @@
|
|||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -5775,8 +6025,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -5937,8 +6193,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6046,8 +6308,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6221,8 +6489,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6345,8 +6619,14 @@
|
|||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Check reject behaviour
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -6486,8 +6766,8 @@
|
|||
<span class="macro">assert!</span>(
|
||||
discovery.scopes_supported
|
||||
== <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
<span class="string">"openid"</span>.to_string(),
|
||||
<span class="string">"read"</span>.to_string(),
|
||||
<span class="string">"supplement"</span>.to_string(),
|
||||
])
|
||||
);
|
||||
|
@ -6552,8 +6832,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6684,8 +6970,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6760,6 +7052,116 @@
|
|||
)
|
||||
}
|
||||
|
||||
<span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_openid_group_claims() {
|
||||
<span class="macro">run_idm_test!</span>(
|
||||
|_qs: <span class="kw-2">&</span>QueryServer, idms: <span class="kw-2">&</span>IdmServer, idms_delayed: <span class="kw-2">&mut </span>IdmServerDelayed| {
|
||||
<span class="comment">// we run the same test as test_idm_oauth2_openid_extensions()
|
||||
// but change the preferred_username setting on the RS
|
||||
</span><span class="kw">let </span>ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||
<span class="kw">let </span>(secret, uat, ident, <span class="kw">_</span>) =
|
||||
setup_oauth2_resource_server(idms, ct, <span class="bool-val">true</span>, <span class="bool-val">false</span>, <span class="bool-val">true</span>);
|
||||
<span class="kw">let </span>client_authz = <span class="prelude-val">Some</span>(base64::encode(<span class="macro">format!</span>(<span class="string">"test_resource_server:{}"</span>, secret)));
|
||||
|
||||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid groups"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
consent_request
|
||||
{
|
||||
consent_token
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">unreachable!</span>();
|
||||
};
|
||||
|
||||
<span class="comment">// == Manually submit the consent token to the permit for the permit_success
|
||||
</span><span class="kw">let </span>permit_success = idms_prox_read
|
||||
.check_oauth2_authorise_permit(<span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, <span class="kw-2">&</span>consent_token, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 permit"</span>);
|
||||
|
||||
<span class="comment">// Assert that the consent was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2ConsentGrant(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="comment">// == Submit the token exchange code.
|
||||
</span><span class="kw">let </span>token_req = AccessTokenRequest {
|
||||
grant_type: <span class="string">"authorization_code"</span>.to_string(),
|
||||
code: permit_success.code,
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
client_id: <span class="prelude-val">None</span>,
|
||||
client_secret: <span class="prelude-val">None</span>,
|
||||
<span class="comment">// From the first step.
|
||||
</span>code_verifier,
|
||||
};
|
||||
|
||||
<span class="kw">let </span>token_response = idms_prox_read
|
||||
.check_oauth2_token_exchange(client_authz.as_deref(), <span class="kw-2">&</span>token_req, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 token exchange"</span>);
|
||||
|
||||
<span class="comment">// Assert that the session creation was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2SessionRecord(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="kw">let </span>id_token = token_response.id_token.expect(<span class="string">"No id_token in response!"</span>);
|
||||
<span class="kw">let </span>access_token = token_response.access_token;
|
||||
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>jwkset = idms_prox_read
|
||||
.oauth2_openid_publickey(<span class="string">"test_resource_server"</span>)
|
||||
.expect(<span class="string">"Failed to get public key"</span>);
|
||||
<span class="kw">let </span>public_jwk = jwkset.keys.pop().expect(<span class="string">"no such jwk"</span>);
|
||||
|
||||
<span class="kw">let </span>jws_validator =
|
||||
JwsValidator::try_from(<span class="kw-2">&</span>public_jwk).expect(<span class="string">"failed to build validator"</span>);
|
||||
|
||||
<span class="kw">let </span>oidc_unverified =
|
||||
OidcUnverified::from_str(<span class="kw-2">&</span>id_token).expect(<span class="string">"Failed to parse id_token"</span>);
|
||||
|
||||
<span class="kw">let </span>iat = ct.as_secs() <span class="kw">as </span>i64;
|
||||
|
||||
<span class="kw">let </span>oidc = oidc_unverified
|
||||
.validate(<span class="kw-2">&</span>jws_validator, iat)
|
||||
.expect(<span class="string">"Failed to verify oidc"</span>);
|
||||
|
||||
<span class="comment">// does our id_token contain the expected groups?
|
||||
</span><span class="macro">assert!</span>(oidc.claims.contains_key(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()));
|
||||
|
||||
<span class="macro">assert!</span>(oidc
|
||||
.claims
|
||||
.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
.expect(<span class="string">"unable to find key"</span>)
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.contains(<span class="kw-2">&</span><span class="macro">serde_json::json!</span>(STR_UUID_IDM_ALL_ACCOUNTS)));
|
||||
|
||||
<span class="comment">// Do the id_token details line up to the userinfo?
|
||||
</span><span class="kw">let </span>userinfo = idms_prox_read
|
||||
.oauth2_openid_userinfo(<span class="string">"test_resource_server"</span>, <span class="kw-2">&</span>access_token, ct)
|
||||
.expect(<span class="string">"failed to get userinfo"</span>);
|
||||
|
||||
<span class="comment">// does the userinfo endpoint provide the same groups?
|
||||
</span><span class="macro">assert!</span>(
|
||||
oidc.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
== userinfo.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
<span class="comment">// Check insecure pkce behaviour.
|
||||
</span><span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_insecure_pkce() {
|
||||
|
@ -6776,8 +7178,14 @@
|
|||
</span><span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Even in disable pkce mode, we will allow pkce
|
||||
</span><span class="kw">let </span>_consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>_consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Check we allow none.
|
||||
</span><span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
|
@ -6837,8 +7245,14 @@
|
|||
<span class="comment">// Check that the id_token is signed with the correct key.
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6913,8 +7327,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -6953,8 +7373,14 @@
|
|||
.expect(<span class="string">"Unable to process uat"</span>);
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>_permit_success =
|
||||
|
@ -7117,8 +7543,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -7317,8 +7749,14 @@
|
|||
);
|
||||
|
||||
<span class="comment">// This does have https
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
|
|
@ -4665,7 +4665,7 @@
|
|||
parent_session_id: Uuid,
|
||||
iat: i64,
|
||||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Account>, OperationError> {
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Arc<Entry<EntrySealed, EntryCommitted>>>, OperationError> {
|
||||
<span class="kw">let </span>entry = <span class="self">self</span>.get_qs_txn().internal_search_uuid(uuid).map_err(|e| {
|
||||
<span class="macro">admin_error!</span>(<span class="question-mark">?</span>e, <span class="string">"check_oauth2_account_uuid_valid failed"</span>);
|
||||
e
|
||||
|
@ -4705,7 +4705,7 @@
|
|||
<span class="macro">security_info!</span>(<span class="string">"The token grace window is in effect. Assuming valid."</span>);
|
||||
};
|
||||
|
||||
Account::try_from_entry_no_groups(entry.as_ref()).map(<span class="prelude-val">Some</span>)
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry))
|
||||
}
|
||||
|
||||
<span class="doccomment">/// For any event/operation to proceed, we need to attach an identity to the
|
||||
|
@ -5638,7 +5638,7 @@
|
|||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><AccessTokenResponse, Oauth2Error> {
|
||||
<span class="self">self</span>.oauth2rs
|
||||
.check_oauth2_token_exchange(client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
.check_oauth2_token_exchange(<span class="self">self</span>, client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
}
|
||||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_introspect(
|
||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
|||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3682">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3901">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<p>This contains the in memory and loaded set of active oauth2 resource server
|
||||
integrations, which are then able to be used an accessed from the IDM layer
|
||||
for operations involving oauth2 authentication processing.</p>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
<!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="Settings of Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc settings</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable Javascript be able to update your settings.</section></noscript><link rel="stylesheet" type="text/css" href="settings.css"><script defer src="settings.js"></script></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="Settings of Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc settings</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable Javascript be able to update your settings.</section></noscript><link rel="stylesheet" type="text/css" href="settings.css"><script defer src="settings.js"></script></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
|
@ -938,7 +938,7 @@
|
|||
<span class="attribute">#[instrument(level = <span class="string">"trace"</span>, skip_all)]
|
||||
</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>try_from_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, OperationError> {
|
||||
<span class="kw">let </span>groups = Group::try_from_account_entry_ro(value, qs)<span class="question-mark">?</span>;
|
||||
<span class="macro">try_from_entry!</span>(value, groups)
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>try_from_account_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><Vec<<span class="self">Self</span>>, OperationError> {
|
||||
<span class="macro">try_from_account_e!</span>(value, qs)
|
||||
}
|
||||
|
|
|
@ -3680,6 +3680,225 @@
|
|||
<span id="3680">3680</span>
|
||||
<span id="3681">3681</span>
|
||||
<span id="3682">3682</span>
|
||||
<span id="3683">3683</span>
|
||||
<span id="3684">3684</span>
|
||||
<span id="3685">3685</span>
|
||||
<span id="3686">3686</span>
|
||||
<span id="3687">3687</span>
|
||||
<span id="3688">3688</span>
|
||||
<span id="3689">3689</span>
|
||||
<span id="3690">3690</span>
|
||||
<span id="3691">3691</span>
|
||||
<span id="3692">3692</span>
|
||||
<span id="3693">3693</span>
|
||||
<span id="3694">3694</span>
|
||||
<span id="3695">3695</span>
|
||||
<span id="3696">3696</span>
|
||||
<span id="3697">3697</span>
|
||||
<span id="3698">3698</span>
|
||||
<span id="3699">3699</span>
|
||||
<span id="3700">3700</span>
|
||||
<span id="3701">3701</span>
|
||||
<span id="3702">3702</span>
|
||||
<span id="3703">3703</span>
|
||||
<span id="3704">3704</span>
|
||||
<span id="3705">3705</span>
|
||||
<span id="3706">3706</span>
|
||||
<span id="3707">3707</span>
|
||||
<span id="3708">3708</span>
|
||||
<span id="3709">3709</span>
|
||||
<span id="3710">3710</span>
|
||||
<span id="3711">3711</span>
|
||||
<span id="3712">3712</span>
|
||||
<span id="3713">3713</span>
|
||||
<span id="3714">3714</span>
|
||||
<span id="3715">3715</span>
|
||||
<span id="3716">3716</span>
|
||||
<span id="3717">3717</span>
|
||||
<span id="3718">3718</span>
|
||||
<span id="3719">3719</span>
|
||||
<span id="3720">3720</span>
|
||||
<span id="3721">3721</span>
|
||||
<span id="3722">3722</span>
|
||||
<span id="3723">3723</span>
|
||||
<span id="3724">3724</span>
|
||||
<span id="3725">3725</span>
|
||||
<span id="3726">3726</span>
|
||||
<span id="3727">3727</span>
|
||||
<span id="3728">3728</span>
|
||||
<span id="3729">3729</span>
|
||||
<span id="3730">3730</span>
|
||||
<span id="3731">3731</span>
|
||||
<span id="3732">3732</span>
|
||||
<span id="3733">3733</span>
|
||||
<span id="3734">3734</span>
|
||||
<span id="3735">3735</span>
|
||||
<span id="3736">3736</span>
|
||||
<span id="3737">3737</span>
|
||||
<span id="3738">3738</span>
|
||||
<span id="3739">3739</span>
|
||||
<span id="3740">3740</span>
|
||||
<span id="3741">3741</span>
|
||||
<span id="3742">3742</span>
|
||||
<span id="3743">3743</span>
|
||||
<span id="3744">3744</span>
|
||||
<span id="3745">3745</span>
|
||||
<span id="3746">3746</span>
|
||||
<span id="3747">3747</span>
|
||||
<span id="3748">3748</span>
|
||||
<span id="3749">3749</span>
|
||||
<span id="3750">3750</span>
|
||||
<span id="3751">3751</span>
|
||||
<span id="3752">3752</span>
|
||||
<span id="3753">3753</span>
|
||||
<span id="3754">3754</span>
|
||||
<span id="3755">3755</span>
|
||||
<span id="3756">3756</span>
|
||||
<span id="3757">3757</span>
|
||||
<span id="3758">3758</span>
|
||||
<span id="3759">3759</span>
|
||||
<span id="3760">3760</span>
|
||||
<span id="3761">3761</span>
|
||||
<span id="3762">3762</span>
|
||||
<span id="3763">3763</span>
|
||||
<span id="3764">3764</span>
|
||||
<span id="3765">3765</span>
|
||||
<span id="3766">3766</span>
|
||||
<span id="3767">3767</span>
|
||||
<span id="3768">3768</span>
|
||||
<span id="3769">3769</span>
|
||||
<span id="3770">3770</span>
|
||||
<span id="3771">3771</span>
|
||||
<span id="3772">3772</span>
|
||||
<span id="3773">3773</span>
|
||||
<span id="3774">3774</span>
|
||||
<span id="3775">3775</span>
|
||||
<span id="3776">3776</span>
|
||||
<span id="3777">3777</span>
|
||||
<span id="3778">3778</span>
|
||||
<span id="3779">3779</span>
|
||||
<span id="3780">3780</span>
|
||||
<span id="3781">3781</span>
|
||||
<span id="3782">3782</span>
|
||||
<span id="3783">3783</span>
|
||||
<span id="3784">3784</span>
|
||||
<span id="3785">3785</span>
|
||||
<span id="3786">3786</span>
|
||||
<span id="3787">3787</span>
|
||||
<span id="3788">3788</span>
|
||||
<span id="3789">3789</span>
|
||||
<span id="3790">3790</span>
|
||||
<span id="3791">3791</span>
|
||||
<span id="3792">3792</span>
|
||||
<span id="3793">3793</span>
|
||||
<span id="3794">3794</span>
|
||||
<span id="3795">3795</span>
|
||||
<span id="3796">3796</span>
|
||||
<span id="3797">3797</span>
|
||||
<span id="3798">3798</span>
|
||||
<span id="3799">3799</span>
|
||||
<span id="3800">3800</span>
|
||||
<span id="3801">3801</span>
|
||||
<span id="3802">3802</span>
|
||||
<span id="3803">3803</span>
|
||||
<span id="3804">3804</span>
|
||||
<span id="3805">3805</span>
|
||||
<span id="3806">3806</span>
|
||||
<span id="3807">3807</span>
|
||||
<span id="3808">3808</span>
|
||||
<span id="3809">3809</span>
|
||||
<span id="3810">3810</span>
|
||||
<span id="3811">3811</span>
|
||||
<span id="3812">3812</span>
|
||||
<span id="3813">3813</span>
|
||||
<span id="3814">3814</span>
|
||||
<span id="3815">3815</span>
|
||||
<span id="3816">3816</span>
|
||||
<span id="3817">3817</span>
|
||||
<span id="3818">3818</span>
|
||||
<span id="3819">3819</span>
|
||||
<span id="3820">3820</span>
|
||||
<span id="3821">3821</span>
|
||||
<span id="3822">3822</span>
|
||||
<span id="3823">3823</span>
|
||||
<span id="3824">3824</span>
|
||||
<span id="3825">3825</span>
|
||||
<span id="3826">3826</span>
|
||||
<span id="3827">3827</span>
|
||||
<span id="3828">3828</span>
|
||||
<span id="3829">3829</span>
|
||||
<span id="3830">3830</span>
|
||||
<span id="3831">3831</span>
|
||||
<span id="3832">3832</span>
|
||||
<span id="3833">3833</span>
|
||||
<span id="3834">3834</span>
|
||||
<span id="3835">3835</span>
|
||||
<span id="3836">3836</span>
|
||||
<span id="3837">3837</span>
|
||||
<span id="3838">3838</span>
|
||||
<span id="3839">3839</span>
|
||||
<span id="3840">3840</span>
|
||||
<span id="3841">3841</span>
|
||||
<span id="3842">3842</span>
|
||||
<span id="3843">3843</span>
|
||||
<span id="3844">3844</span>
|
||||
<span id="3845">3845</span>
|
||||
<span id="3846">3846</span>
|
||||
<span id="3847">3847</span>
|
||||
<span id="3848">3848</span>
|
||||
<span id="3849">3849</span>
|
||||
<span id="3850">3850</span>
|
||||
<span id="3851">3851</span>
|
||||
<span id="3852">3852</span>
|
||||
<span id="3853">3853</span>
|
||||
<span id="3854">3854</span>
|
||||
<span id="3855">3855</span>
|
||||
<span id="3856">3856</span>
|
||||
<span id="3857">3857</span>
|
||||
<span id="3858">3858</span>
|
||||
<span id="3859">3859</span>
|
||||
<span id="3860">3860</span>
|
||||
<span id="3861">3861</span>
|
||||
<span id="3862">3862</span>
|
||||
<span id="3863">3863</span>
|
||||
<span id="3864">3864</span>
|
||||
<span id="3865">3865</span>
|
||||
<span id="3866">3866</span>
|
||||
<span id="3867">3867</span>
|
||||
<span id="3868">3868</span>
|
||||
<span id="3869">3869</span>
|
||||
<span id="3870">3870</span>
|
||||
<span id="3871">3871</span>
|
||||
<span id="3872">3872</span>
|
||||
<span id="3873">3873</span>
|
||||
<span id="3874">3874</span>
|
||||
<span id="3875">3875</span>
|
||||
<span id="3876">3876</span>
|
||||
<span id="3877">3877</span>
|
||||
<span id="3878">3878</span>
|
||||
<span id="3879">3879</span>
|
||||
<span id="3880">3880</span>
|
||||
<span id="3881">3881</span>
|
||||
<span id="3882">3882</span>
|
||||
<span id="3883">3883</span>
|
||||
<span id="3884">3884</span>
|
||||
<span id="3885">3885</span>
|
||||
<span id="3886">3886</span>
|
||||
<span id="3887">3887</span>
|
||||
<span id="3888">3888</span>
|
||||
<span id="3889">3889</span>
|
||||
<span id="3890">3890</span>
|
||||
<span id="3891">3891</span>
|
||||
<span id="3892">3892</span>
|
||||
<span id="3893">3893</span>
|
||||
<span id="3894">3894</span>
|
||||
<span id="3895">3895</span>
|
||||
<span id="3896">3896</span>
|
||||
<span id="3897">3897</span>
|
||||
<span id="3898">3898</span>
|
||||
<span id="3899">3899</span>
|
||||
<span id="3900">3900</span>
|
||||
<span id="3901">3901</span>
|
||||
</pre><pre class="rust"><code><span class="doccomment">//! Oauth2 resource server configurations
|
||||
//!
|
||||
//! This contains the in memory and loaded set of active oauth2 resource server
|
||||
|
@ -3716,6 +3935,7 @@
|
|||
<span class="kw">use </span>url::{Origin, Url};
|
||||
|
||||
<span class="kw">use </span><span class="kw">crate</span>::identity::IdentityId;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::account::Account;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::delayed::{DelayedAction, Oauth2ConsentGrant, Oauth2SessionRecord};
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::server::{
|
||||
IdmServerProxyReadTransaction, IdmServerProxyWriteTransaction, IdmServerTransaction,
|
||||
|
@ -4637,6 +4857,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_exchange(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
client_authz: <span class="prelude-ty">Option</span><<span class="kw-2">&</span>str>,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4673,7 +4894,7 @@
|
|||
// TODO: add refresh token grant type.
|
||||
// If it's a refresh token grant, are the consent permissions the same?
|
||||
</span><span class="kw">if </span>token_req.grant_type == <span class="string">"authorization_code" </span>{
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(o2rs, token_req, ct, async_tx)
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(idms, o2rs, token_req, ct, async_tx)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">admin_warn!</span>(<span class="string">"Invalid oauth2 grant_type (should be 'authorization_code')"</span>);
|
||||
<span class="prelude-val">Err</span>(Oauth2Error::InvalidRequest)
|
||||
|
@ -4682,6 +4903,7 @@
|
|||
|
||||
<span class="kw">fn </span>check_oauth2_token_exchange_authorization_code(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
o2rs: <span class="kw-2">&</span>Oauth2RS,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4776,9 +4998,7 @@
|
|||
<span class="prelude-val">Some</span>(code_xchg.scopes.join(<span class="string">" "</span>))
|
||||
};
|
||||
|
||||
<span class="kw">let </span>scope_set: BTreeSet<String> = code_xchg.scopes.iter().cloned().collect();
|
||||
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>scope_set.contains(<span class="string">"openid"</span>) {
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>code_xchg.scopes.contains(<span class="kw-2">&</span><span class="string">"openid"</span>.to_string()) {
|
||||
<span class="comment">// TODO: Scopes map to claims:
|
||||
//
|
||||
// * profile - (name, family\_name, given\_name, middle\_name, nickname, preferred\_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
|
@ -4791,24 +5011,7 @@
|
|||
// TODO: Can the user consent to which claims are released? Today as we don't support most
|
||||
// of them anyway, no, but in the future, we can stash these to the consent req.
|
||||
|
||||
</span><span class="macro">admin_warn!</span>(<span class="string">"prefer_short_username: {:?}"</span>, o2rs.prefer_short_username);
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.name().to_string())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scope_set.contains(<span class="string">"email"</span>) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = code_xchg.uat.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
<span class="comment">// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
|
||||
// amr == auth method
|
||||
</span><span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[code_xchg.uat.auth_type.to_string()]);
|
||||
|
@ -4818,6 +5021,19 @@
|
|||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>idms.qs_read.internal_search_uuid(code_xchg.uat.uuid) {
|
||||
<span class="prelude-val">Ok</span>(entry) => entry,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
|
||||
<span class="kw">let </span>oidc = OidcToken {
|
||||
iss,
|
||||
sub: OidcSubject::U(code_xchg.uat.uuid),
|
||||
|
@ -4832,17 +5048,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(o2rs.name.clone()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(code_xchg.uat.displayname.clone()),
|
||||
<span class="comment">// Map from spn
|
||||
</span>scopes: code_xchg.scopes.clone(),
|
||||
email,
|
||||
email_verified,
|
||||
preferred_username,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
};
|
||||
|
||||
<span class="macro">trace!</span>(<span class="question-mark">?</span>oidc);
|
||||
|
@ -4972,17 +5179,22 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
<span class="string">"access token has account not valid, returning inactive"
|
||||
<span class="string">"access token has no account not valid, returning inactive"
|
||||
</span>);
|
||||
<span class="kw">return </span><span class="prelude-val">Ok</span>(AccessTokenIntrospectResponse::inactive());
|
||||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_no_groups(<span class="kw-2">&</span>entry) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="kw">let </span>scope = <span class="kw">if </span>scopes.is_empty() {
|
||||
|
@ -5064,8 +5276,8 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
|
@ -5075,26 +5287,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn)
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[auth_type.to_string()]);
|
||||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="prelude-val">Ok</span>(OidcToken {
|
||||
|
@ -5111,16 +5315,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(client_id.to_string()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes,
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
})
|
||||
}
|
||||
<span class="comment">// https://openid.net/specs/openid-connect-basic-1_0.html#UserInfoErrorResponse
|
||||
|
@ -5259,6 +5455,47 @@
|
|||
<span class="prelude-val">Ok</span>((client_id.to_string(), secret.to_string()))
|
||||
}
|
||||
|
||||
<span class="kw">fn </span>s_claims_for_account(o2rs: <span class="kw-2">&</span>Oauth2RS, account: <span class="kw-2">&</span>Account, scopes: <span class="kw-2">&</span>[String]) -> OidcClaims {
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name.clone())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = <span class="kw-2">&</span>account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp.clone()), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes: scopes.to_vec(),
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
<span class="kw">fn </span>extra_claims_for_account(
|
||||
account: <span class="kw-2">&</span>Account,
|
||||
scopes: <span class="kw-2">&</span>[String],
|
||||
) -> BTreeMap<String, serde_json::Value> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>extra_claims = BTreeMap::new();
|
||||
<span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()) {
|
||||
extra_claims.insert(
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
account.groups.iter().map(|x| x.to_proto().uuid).collect(),
|
||||
);
|
||||
}
|
||||
<span class="kw">return </span>extra_claims;
|
||||
}
|
||||
|
||||
<span class="attribute">#[cfg(test)]
|
||||
</span><span class="kw">mod </span>tests {
|
||||
<span class="kw">use </span>std::convert::TryFrom;
|
||||
|
@ -5299,7 +5536,8 @@
|
|||
<span class="macro-nonterminal">$ident</span>:expr,
|
||||
<span class="macro-nonterminal">$uat</span>:expr,
|
||||
<span class="macro-nonterminal">$ct</span>:expr,
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr,
|
||||
<span class="macro-nonterminal">$scope</span>:expr
|
||||
) => {{
|
||||
<span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
response_type: <span class="string">"code"</span>.to_string(),
|
||||
|
@ -5310,7 +5548,7 @@
|
|||
code_challenge_method: CodeChallengeMethod::S256,
|
||||
}),
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
scope: <span class="string">"openid"</span>.to_string(),
|
||||
scope: <span class="macro-nonterminal">$scope</span>,
|
||||
nonce: <span class="prelude-val">Some</span>(<span class="string">"abcdef"</span>.to_string()),
|
||||
oidc_ext: Default::default(),
|
||||
unknown_keys: Default::default(),
|
||||
|
@ -5348,7 +5586,7 @@
|
|||
<span class="comment">// System admins
|
||||
</span>(
|
||||
<span class="string">"oauth2_rs_scope_map"</span>,
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"read"</span>.to_string()])
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"groups"</span>.to_string()])
|
||||
.expect(<span class="string">"invalid oauthscope"</span>)
|
||||
),
|
||||
(
|
||||
|
@ -5448,8 +5686,14 @@
|
|||
// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -5702,8 +5946,14 @@
|
|||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -5775,8 +6025,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -5937,8 +6193,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6046,8 +6308,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6221,8 +6489,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6345,8 +6619,14 @@
|
|||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Check reject behaviour
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -6486,8 +6766,8 @@
|
|||
<span class="macro">assert!</span>(
|
||||
discovery.scopes_supported
|
||||
== <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
<span class="string">"openid"</span>.to_string(),
|
||||
<span class="string">"read"</span>.to_string(),
|
||||
<span class="string">"supplement"</span>.to_string(),
|
||||
])
|
||||
);
|
||||
|
@ -6552,8 +6832,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6684,8 +6970,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6760,6 +7052,116 @@
|
|||
)
|
||||
}
|
||||
|
||||
<span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_openid_group_claims() {
|
||||
<span class="macro">run_idm_test!</span>(
|
||||
|_qs: <span class="kw-2">&</span>QueryServer, idms: <span class="kw-2">&</span>IdmServer, idms_delayed: <span class="kw-2">&mut </span>IdmServerDelayed| {
|
||||
<span class="comment">// we run the same test as test_idm_oauth2_openid_extensions()
|
||||
// but change the preferred_username setting on the RS
|
||||
</span><span class="kw">let </span>ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||
<span class="kw">let </span>(secret, uat, ident, <span class="kw">_</span>) =
|
||||
setup_oauth2_resource_server(idms, ct, <span class="bool-val">true</span>, <span class="bool-val">false</span>, <span class="bool-val">true</span>);
|
||||
<span class="kw">let </span>client_authz = <span class="prelude-val">Some</span>(base64::encode(<span class="macro">format!</span>(<span class="string">"test_resource_server:{}"</span>, secret)));
|
||||
|
||||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid groups"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
consent_request
|
||||
{
|
||||
consent_token
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">unreachable!</span>();
|
||||
};
|
||||
|
||||
<span class="comment">// == Manually submit the consent token to the permit for the permit_success
|
||||
</span><span class="kw">let </span>permit_success = idms_prox_read
|
||||
.check_oauth2_authorise_permit(<span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, <span class="kw-2">&</span>consent_token, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 permit"</span>);
|
||||
|
||||
<span class="comment">// Assert that the consent was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2ConsentGrant(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="comment">// == Submit the token exchange code.
|
||||
</span><span class="kw">let </span>token_req = AccessTokenRequest {
|
||||
grant_type: <span class="string">"authorization_code"</span>.to_string(),
|
||||
code: permit_success.code,
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
client_id: <span class="prelude-val">None</span>,
|
||||
client_secret: <span class="prelude-val">None</span>,
|
||||
<span class="comment">// From the first step.
|
||||
</span>code_verifier,
|
||||
};
|
||||
|
||||
<span class="kw">let </span>token_response = idms_prox_read
|
||||
.check_oauth2_token_exchange(client_authz.as_deref(), <span class="kw-2">&</span>token_req, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 token exchange"</span>);
|
||||
|
||||
<span class="comment">// Assert that the session creation was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2SessionRecord(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="kw">let </span>id_token = token_response.id_token.expect(<span class="string">"No id_token in response!"</span>);
|
||||
<span class="kw">let </span>access_token = token_response.access_token;
|
||||
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>jwkset = idms_prox_read
|
||||
.oauth2_openid_publickey(<span class="string">"test_resource_server"</span>)
|
||||
.expect(<span class="string">"Failed to get public key"</span>);
|
||||
<span class="kw">let </span>public_jwk = jwkset.keys.pop().expect(<span class="string">"no such jwk"</span>);
|
||||
|
||||
<span class="kw">let </span>jws_validator =
|
||||
JwsValidator::try_from(<span class="kw-2">&</span>public_jwk).expect(<span class="string">"failed to build validator"</span>);
|
||||
|
||||
<span class="kw">let </span>oidc_unverified =
|
||||
OidcUnverified::from_str(<span class="kw-2">&</span>id_token).expect(<span class="string">"Failed to parse id_token"</span>);
|
||||
|
||||
<span class="kw">let </span>iat = ct.as_secs() <span class="kw">as </span>i64;
|
||||
|
||||
<span class="kw">let </span>oidc = oidc_unverified
|
||||
.validate(<span class="kw-2">&</span>jws_validator, iat)
|
||||
.expect(<span class="string">"Failed to verify oidc"</span>);
|
||||
|
||||
<span class="comment">// does our id_token contain the expected groups?
|
||||
</span><span class="macro">assert!</span>(oidc.claims.contains_key(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()));
|
||||
|
||||
<span class="macro">assert!</span>(oidc
|
||||
.claims
|
||||
.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
.expect(<span class="string">"unable to find key"</span>)
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.contains(<span class="kw-2">&</span><span class="macro">serde_json::json!</span>(STR_UUID_IDM_ALL_ACCOUNTS)));
|
||||
|
||||
<span class="comment">// Do the id_token details line up to the userinfo?
|
||||
</span><span class="kw">let </span>userinfo = idms_prox_read
|
||||
.oauth2_openid_userinfo(<span class="string">"test_resource_server"</span>, <span class="kw-2">&</span>access_token, ct)
|
||||
.expect(<span class="string">"failed to get userinfo"</span>);
|
||||
|
||||
<span class="comment">// does the userinfo endpoint provide the same groups?
|
||||
</span><span class="macro">assert!</span>(
|
||||
oidc.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
== userinfo.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
<span class="comment">// Check insecure pkce behaviour.
|
||||
</span><span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_insecure_pkce() {
|
||||
|
@ -6776,8 +7178,14 @@
|
|||
</span><span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Even in disable pkce mode, we will allow pkce
|
||||
</span><span class="kw">let </span>_consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>_consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Check we allow none.
|
||||
</span><span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
|
@ -6837,8 +7245,14 @@
|
|||
<span class="comment">// Check that the id_token is signed with the correct key.
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6913,8 +7327,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -6953,8 +7373,14 @@
|
|||
.expect(<span class="string">"Unable to process uat"</span>);
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>_permit_success =
|
||||
|
@ -7117,8 +7543,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -7317,8 +7749,14 @@
|
|||
);
|
||||
|
||||
<span class="comment">// This does have https
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
|
|
@ -4665,7 +4665,7 @@
|
|||
parent_session_id: Uuid,
|
||||
iat: i64,
|
||||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Account>, OperationError> {
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Arc<Entry<EntrySealed, EntryCommitted>>>, OperationError> {
|
||||
<span class="kw">let </span>entry = <span class="self">self</span>.get_qs_txn().internal_search_uuid(uuid).map_err(|e| {
|
||||
<span class="macro">admin_error!</span>(<span class="question-mark">?</span>e, <span class="string">"check_oauth2_account_uuid_valid failed"</span>);
|
||||
e
|
||||
|
@ -4705,7 +4705,7 @@
|
|||
<span class="macro">security_info!</span>(<span class="string">"The token grace window is in effect. Assuming valid."</span>);
|
||||
};
|
||||
|
||||
Account::try_from_entry_no_groups(entry.as_ref()).map(<span class="prelude-val">Some</span>)
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry))
|
||||
}
|
||||
|
||||
<span class="doccomment">/// For any event/operation to proceed, we need to attach an identity to the
|
||||
|
@ -5638,7 +5638,7 @@
|
|||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><AccessTokenResponse, Oauth2Error> {
|
||||
<span class="self">self</span>.oauth2rs
|
||||
.check_oauth2_token_exchange(client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
.check_oauth2_token_exchange(<span class="self">self</span>, client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
}
|
||||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_introspect(
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3682">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3901">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<p>This contains the in memory and loaded set of active oauth2 resource server
|
||||
integrations, which are then able to be used an accessed from the IDM layer
|
||||
for operations involving oauth2 authentication processing.</p>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
<!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="Settings of Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc settings</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable Javascript be able to update your settings.</section></noscript><link rel="stylesheet" type="text/css" href="settings.css"><script defer src="settings.js"></script></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="Settings of Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc settings</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable Javascript be able to update your settings.</section></noscript><link rel="stylesheet" type="text/css" href="settings.css"><script defer src="settings.js"></script></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
|
@ -938,7 +938,7 @@
|
|||
<span class="attribute">#[instrument(level = <span class="string">"trace"</span>, skip_all)]
|
||||
</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>try_from_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, OperationError> {
|
||||
<span class="kw">let </span>groups = Group::try_from_account_entry_ro(value, qs)<span class="question-mark">?</span>;
|
||||
<span class="macro">try_from_entry!</span>(value, groups)
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>try_from_account_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><Vec<<span class="self">Self</span>>, OperationError> {
|
||||
<span class="macro">try_from_account_e!</span>(value, qs)
|
||||
}
|
||||
|
|
|
@ -3680,6 +3680,225 @@
|
|||
<span id="3680">3680</span>
|
||||
<span id="3681">3681</span>
|
||||
<span id="3682">3682</span>
|
||||
<span id="3683">3683</span>
|
||||
<span id="3684">3684</span>
|
||||
<span id="3685">3685</span>
|
||||
<span id="3686">3686</span>
|
||||
<span id="3687">3687</span>
|
||||
<span id="3688">3688</span>
|
||||
<span id="3689">3689</span>
|
||||
<span id="3690">3690</span>
|
||||
<span id="3691">3691</span>
|
||||
<span id="3692">3692</span>
|
||||
<span id="3693">3693</span>
|
||||
<span id="3694">3694</span>
|
||||
<span id="3695">3695</span>
|
||||
<span id="3696">3696</span>
|
||||
<span id="3697">3697</span>
|
||||
<span id="3698">3698</span>
|
||||
<span id="3699">3699</span>
|
||||
<span id="3700">3700</span>
|
||||
<span id="3701">3701</span>
|
||||
<span id="3702">3702</span>
|
||||
<span id="3703">3703</span>
|
||||
<span id="3704">3704</span>
|
||||
<span id="3705">3705</span>
|
||||
<span id="3706">3706</span>
|
||||
<span id="3707">3707</span>
|
||||
<span id="3708">3708</span>
|
||||
<span id="3709">3709</span>
|
||||
<span id="3710">3710</span>
|
||||
<span id="3711">3711</span>
|
||||
<span id="3712">3712</span>
|
||||
<span id="3713">3713</span>
|
||||
<span id="3714">3714</span>
|
||||
<span id="3715">3715</span>
|
||||
<span id="3716">3716</span>
|
||||
<span id="3717">3717</span>
|
||||
<span id="3718">3718</span>
|
||||
<span id="3719">3719</span>
|
||||
<span id="3720">3720</span>
|
||||
<span id="3721">3721</span>
|
||||
<span id="3722">3722</span>
|
||||
<span id="3723">3723</span>
|
||||
<span id="3724">3724</span>
|
||||
<span id="3725">3725</span>
|
||||
<span id="3726">3726</span>
|
||||
<span id="3727">3727</span>
|
||||
<span id="3728">3728</span>
|
||||
<span id="3729">3729</span>
|
||||
<span id="3730">3730</span>
|
||||
<span id="3731">3731</span>
|
||||
<span id="3732">3732</span>
|
||||
<span id="3733">3733</span>
|
||||
<span id="3734">3734</span>
|
||||
<span id="3735">3735</span>
|
||||
<span id="3736">3736</span>
|
||||
<span id="3737">3737</span>
|
||||
<span id="3738">3738</span>
|
||||
<span id="3739">3739</span>
|
||||
<span id="3740">3740</span>
|
||||
<span id="3741">3741</span>
|
||||
<span id="3742">3742</span>
|
||||
<span id="3743">3743</span>
|
||||
<span id="3744">3744</span>
|
||||
<span id="3745">3745</span>
|
||||
<span id="3746">3746</span>
|
||||
<span id="3747">3747</span>
|
||||
<span id="3748">3748</span>
|
||||
<span id="3749">3749</span>
|
||||
<span id="3750">3750</span>
|
||||
<span id="3751">3751</span>
|
||||
<span id="3752">3752</span>
|
||||
<span id="3753">3753</span>
|
||||
<span id="3754">3754</span>
|
||||
<span id="3755">3755</span>
|
||||
<span id="3756">3756</span>
|
||||
<span id="3757">3757</span>
|
||||
<span id="3758">3758</span>
|
||||
<span id="3759">3759</span>
|
||||
<span id="3760">3760</span>
|
||||
<span id="3761">3761</span>
|
||||
<span id="3762">3762</span>
|
||||
<span id="3763">3763</span>
|
||||
<span id="3764">3764</span>
|
||||
<span id="3765">3765</span>
|
||||
<span id="3766">3766</span>
|
||||
<span id="3767">3767</span>
|
||||
<span id="3768">3768</span>
|
||||
<span id="3769">3769</span>
|
||||
<span id="3770">3770</span>
|
||||
<span id="3771">3771</span>
|
||||
<span id="3772">3772</span>
|
||||
<span id="3773">3773</span>
|
||||
<span id="3774">3774</span>
|
||||
<span id="3775">3775</span>
|
||||
<span id="3776">3776</span>
|
||||
<span id="3777">3777</span>
|
||||
<span id="3778">3778</span>
|
||||
<span id="3779">3779</span>
|
||||
<span id="3780">3780</span>
|
||||
<span id="3781">3781</span>
|
||||
<span id="3782">3782</span>
|
||||
<span id="3783">3783</span>
|
||||
<span id="3784">3784</span>
|
||||
<span id="3785">3785</span>
|
||||
<span id="3786">3786</span>
|
||||
<span id="3787">3787</span>
|
||||
<span id="3788">3788</span>
|
||||
<span id="3789">3789</span>
|
||||
<span id="3790">3790</span>
|
||||
<span id="3791">3791</span>
|
||||
<span id="3792">3792</span>
|
||||
<span id="3793">3793</span>
|
||||
<span id="3794">3794</span>
|
||||
<span id="3795">3795</span>
|
||||
<span id="3796">3796</span>
|
||||
<span id="3797">3797</span>
|
||||
<span id="3798">3798</span>
|
||||
<span id="3799">3799</span>
|
||||
<span id="3800">3800</span>
|
||||
<span id="3801">3801</span>
|
||||
<span id="3802">3802</span>
|
||||
<span id="3803">3803</span>
|
||||
<span id="3804">3804</span>
|
||||
<span id="3805">3805</span>
|
||||
<span id="3806">3806</span>
|
||||
<span id="3807">3807</span>
|
||||
<span id="3808">3808</span>
|
||||
<span id="3809">3809</span>
|
||||
<span id="3810">3810</span>
|
||||
<span id="3811">3811</span>
|
||||
<span id="3812">3812</span>
|
||||
<span id="3813">3813</span>
|
||||
<span id="3814">3814</span>
|
||||
<span id="3815">3815</span>
|
||||
<span id="3816">3816</span>
|
||||
<span id="3817">3817</span>
|
||||
<span id="3818">3818</span>
|
||||
<span id="3819">3819</span>
|
||||
<span id="3820">3820</span>
|
||||
<span id="3821">3821</span>
|
||||
<span id="3822">3822</span>
|
||||
<span id="3823">3823</span>
|
||||
<span id="3824">3824</span>
|
||||
<span id="3825">3825</span>
|
||||
<span id="3826">3826</span>
|
||||
<span id="3827">3827</span>
|
||||
<span id="3828">3828</span>
|
||||
<span id="3829">3829</span>
|
||||
<span id="3830">3830</span>
|
||||
<span id="3831">3831</span>
|
||||
<span id="3832">3832</span>
|
||||
<span id="3833">3833</span>
|
||||
<span id="3834">3834</span>
|
||||
<span id="3835">3835</span>
|
||||
<span id="3836">3836</span>
|
||||
<span id="3837">3837</span>
|
||||
<span id="3838">3838</span>
|
||||
<span id="3839">3839</span>
|
||||
<span id="3840">3840</span>
|
||||
<span id="3841">3841</span>
|
||||
<span id="3842">3842</span>
|
||||
<span id="3843">3843</span>
|
||||
<span id="3844">3844</span>
|
||||
<span id="3845">3845</span>
|
||||
<span id="3846">3846</span>
|
||||
<span id="3847">3847</span>
|
||||
<span id="3848">3848</span>
|
||||
<span id="3849">3849</span>
|
||||
<span id="3850">3850</span>
|
||||
<span id="3851">3851</span>
|
||||
<span id="3852">3852</span>
|
||||
<span id="3853">3853</span>
|
||||
<span id="3854">3854</span>
|
||||
<span id="3855">3855</span>
|
||||
<span id="3856">3856</span>
|
||||
<span id="3857">3857</span>
|
||||
<span id="3858">3858</span>
|
||||
<span id="3859">3859</span>
|
||||
<span id="3860">3860</span>
|
||||
<span id="3861">3861</span>
|
||||
<span id="3862">3862</span>
|
||||
<span id="3863">3863</span>
|
||||
<span id="3864">3864</span>
|
||||
<span id="3865">3865</span>
|
||||
<span id="3866">3866</span>
|
||||
<span id="3867">3867</span>
|
||||
<span id="3868">3868</span>
|
||||
<span id="3869">3869</span>
|
||||
<span id="3870">3870</span>
|
||||
<span id="3871">3871</span>
|
||||
<span id="3872">3872</span>
|
||||
<span id="3873">3873</span>
|
||||
<span id="3874">3874</span>
|
||||
<span id="3875">3875</span>
|
||||
<span id="3876">3876</span>
|
||||
<span id="3877">3877</span>
|
||||
<span id="3878">3878</span>
|
||||
<span id="3879">3879</span>
|
||||
<span id="3880">3880</span>
|
||||
<span id="3881">3881</span>
|
||||
<span id="3882">3882</span>
|
||||
<span id="3883">3883</span>
|
||||
<span id="3884">3884</span>
|
||||
<span id="3885">3885</span>
|
||||
<span id="3886">3886</span>
|
||||
<span id="3887">3887</span>
|
||||
<span id="3888">3888</span>
|
||||
<span id="3889">3889</span>
|
||||
<span id="3890">3890</span>
|
||||
<span id="3891">3891</span>
|
||||
<span id="3892">3892</span>
|
||||
<span id="3893">3893</span>
|
||||
<span id="3894">3894</span>
|
||||
<span id="3895">3895</span>
|
||||
<span id="3896">3896</span>
|
||||
<span id="3897">3897</span>
|
||||
<span id="3898">3898</span>
|
||||
<span id="3899">3899</span>
|
||||
<span id="3900">3900</span>
|
||||
<span id="3901">3901</span>
|
||||
</pre><pre class="rust"><code><span class="doccomment">//! Oauth2 resource server configurations
|
||||
//!
|
||||
//! This contains the in memory and loaded set of active oauth2 resource server
|
||||
|
@ -3716,6 +3935,7 @@
|
|||
<span class="kw">use </span>url::{Origin, Url};
|
||||
|
||||
<span class="kw">use </span><span class="kw">crate</span>::identity::IdentityId;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::account::Account;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::delayed::{DelayedAction, Oauth2ConsentGrant, Oauth2SessionRecord};
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::server::{
|
||||
IdmServerProxyReadTransaction, IdmServerProxyWriteTransaction, IdmServerTransaction,
|
||||
|
@ -4637,6 +4857,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_exchange(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
client_authz: <span class="prelude-ty">Option</span><<span class="kw-2">&</span>str>,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4673,7 +4894,7 @@
|
|||
// TODO: add refresh token grant type.
|
||||
// If it's a refresh token grant, are the consent permissions the same?
|
||||
</span><span class="kw">if </span>token_req.grant_type == <span class="string">"authorization_code" </span>{
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(o2rs, token_req, ct, async_tx)
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(idms, o2rs, token_req, ct, async_tx)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">admin_warn!</span>(<span class="string">"Invalid oauth2 grant_type (should be 'authorization_code')"</span>);
|
||||
<span class="prelude-val">Err</span>(Oauth2Error::InvalidRequest)
|
||||
|
@ -4682,6 +4903,7 @@
|
|||
|
||||
<span class="kw">fn </span>check_oauth2_token_exchange_authorization_code(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
o2rs: <span class="kw-2">&</span>Oauth2RS,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4776,9 +4998,7 @@
|
|||
<span class="prelude-val">Some</span>(code_xchg.scopes.join(<span class="string">" "</span>))
|
||||
};
|
||||
|
||||
<span class="kw">let </span>scope_set: BTreeSet<String> = code_xchg.scopes.iter().cloned().collect();
|
||||
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>scope_set.contains(<span class="string">"openid"</span>) {
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>code_xchg.scopes.contains(<span class="kw-2">&</span><span class="string">"openid"</span>.to_string()) {
|
||||
<span class="comment">// TODO: Scopes map to claims:
|
||||
//
|
||||
// * profile - (name, family\_name, given\_name, middle\_name, nickname, preferred\_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
|
@ -4791,24 +5011,7 @@
|
|||
// TODO: Can the user consent to which claims are released? Today as we don't support most
|
||||
// of them anyway, no, but in the future, we can stash these to the consent req.
|
||||
|
||||
</span><span class="macro">admin_warn!</span>(<span class="string">"prefer_short_username: {:?}"</span>, o2rs.prefer_short_username);
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.name().to_string())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scope_set.contains(<span class="string">"email"</span>) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = code_xchg.uat.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
<span class="comment">// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
|
||||
// amr == auth method
|
||||
</span><span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[code_xchg.uat.auth_type.to_string()]);
|
||||
|
@ -4818,6 +5021,19 @@
|
|||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>idms.qs_read.internal_search_uuid(code_xchg.uat.uuid) {
|
||||
<span class="prelude-val">Ok</span>(entry) => entry,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
|
||||
<span class="kw">let </span>oidc = OidcToken {
|
||||
iss,
|
||||
sub: OidcSubject::U(code_xchg.uat.uuid),
|
||||
|
@ -4832,17 +5048,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(o2rs.name.clone()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(code_xchg.uat.displayname.clone()),
|
||||
<span class="comment">// Map from spn
|
||||
</span>scopes: code_xchg.scopes.clone(),
|
||||
email,
|
||||
email_verified,
|
||||
preferred_username,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
};
|
||||
|
||||
<span class="macro">trace!</span>(<span class="question-mark">?</span>oidc);
|
||||
|
@ -4972,17 +5179,22 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
<span class="string">"access token has account not valid, returning inactive"
|
||||
<span class="string">"access token has no account not valid, returning inactive"
|
||||
</span>);
|
||||
<span class="kw">return </span><span class="prelude-val">Ok</span>(AccessTokenIntrospectResponse::inactive());
|
||||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_no_groups(<span class="kw-2">&</span>entry) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="kw">let </span>scope = <span class="kw">if </span>scopes.is_empty() {
|
||||
|
@ -5064,8 +5276,8 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
|
@ -5075,26 +5287,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn)
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[auth_type.to_string()]);
|
||||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="prelude-val">Ok</span>(OidcToken {
|
||||
|
@ -5111,16 +5315,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(client_id.to_string()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes,
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
})
|
||||
}
|
||||
<span class="comment">// https://openid.net/specs/openid-connect-basic-1_0.html#UserInfoErrorResponse
|
||||
|
@ -5259,6 +5455,47 @@
|
|||
<span class="prelude-val">Ok</span>((client_id.to_string(), secret.to_string()))
|
||||
}
|
||||
|
||||
<span class="kw">fn </span>s_claims_for_account(o2rs: <span class="kw-2">&</span>Oauth2RS, account: <span class="kw-2">&</span>Account, scopes: <span class="kw-2">&</span>[String]) -> OidcClaims {
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name.clone())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = <span class="kw-2">&</span>account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp.clone()), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes: scopes.to_vec(),
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
<span class="kw">fn </span>extra_claims_for_account(
|
||||
account: <span class="kw-2">&</span>Account,
|
||||
scopes: <span class="kw-2">&</span>[String],
|
||||
) -> BTreeMap<String, serde_json::Value> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>extra_claims = BTreeMap::new();
|
||||
<span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()) {
|
||||
extra_claims.insert(
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
account.groups.iter().map(|x| x.to_proto().uuid).collect(),
|
||||
);
|
||||
}
|
||||
<span class="kw">return </span>extra_claims;
|
||||
}
|
||||
|
||||
<span class="attribute">#[cfg(test)]
|
||||
</span><span class="kw">mod </span>tests {
|
||||
<span class="kw">use </span>std::convert::TryFrom;
|
||||
|
@ -5299,7 +5536,8 @@
|
|||
<span class="macro-nonterminal">$ident</span>:expr,
|
||||
<span class="macro-nonterminal">$uat</span>:expr,
|
||||
<span class="macro-nonterminal">$ct</span>:expr,
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr,
|
||||
<span class="macro-nonterminal">$scope</span>:expr
|
||||
) => {{
|
||||
<span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
response_type: <span class="string">"code"</span>.to_string(),
|
||||
|
@ -5310,7 +5548,7 @@
|
|||
code_challenge_method: CodeChallengeMethod::S256,
|
||||
}),
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
scope: <span class="string">"openid"</span>.to_string(),
|
||||
scope: <span class="macro-nonterminal">$scope</span>,
|
||||
nonce: <span class="prelude-val">Some</span>(<span class="string">"abcdef"</span>.to_string()),
|
||||
oidc_ext: Default::default(),
|
||||
unknown_keys: Default::default(),
|
||||
|
@ -5348,7 +5586,7 @@
|
|||
<span class="comment">// System admins
|
||||
</span>(
|
||||
<span class="string">"oauth2_rs_scope_map"</span>,
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"read"</span>.to_string()])
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"groups"</span>.to_string()])
|
||||
.expect(<span class="string">"invalid oauthscope"</span>)
|
||||
),
|
||||
(
|
||||
|
@ -5448,8 +5686,14 @@
|
|||
// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -5702,8 +5946,14 @@
|
|||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -5775,8 +6025,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -5937,8 +6193,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6046,8 +6308,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6221,8 +6489,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6345,8 +6619,14 @@
|
|||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Check reject behaviour
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -6486,8 +6766,8 @@
|
|||
<span class="macro">assert!</span>(
|
||||
discovery.scopes_supported
|
||||
== <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
<span class="string">"openid"</span>.to_string(),
|
||||
<span class="string">"read"</span>.to_string(),
|
||||
<span class="string">"supplement"</span>.to_string(),
|
||||
])
|
||||
);
|
||||
|
@ -6552,8 +6832,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6684,8 +6970,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6760,6 +7052,116 @@
|
|||
)
|
||||
}
|
||||
|
||||
<span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_openid_group_claims() {
|
||||
<span class="macro">run_idm_test!</span>(
|
||||
|_qs: <span class="kw-2">&</span>QueryServer, idms: <span class="kw-2">&</span>IdmServer, idms_delayed: <span class="kw-2">&mut </span>IdmServerDelayed| {
|
||||
<span class="comment">// we run the same test as test_idm_oauth2_openid_extensions()
|
||||
// but change the preferred_username setting on the RS
|
||||
</span><span class="kw">let </span>ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||
<span class="kw">let </span>(secret, uat, ident, <span class="kw">_</span>) =
|
||||
setup_oauth2_resource_server(idms, ct, <span class="bool-val">true</span>, <span class="bool-val">false</span>, <span class="bool-val">true</span>);
|
||||
<span class="kw">let </span>client_authz = <span class="prelude-val">Some</span>(base64::encode(<span class="macro">format!</span>(<span class="string">"test_resource_server:{}"</span>, secret)));
|
||||
|
||||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid groups"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
consent_request
|
||||
{
|
||||
consent_token
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">unreachable!</span>();
|
||||
};
|
||||
|
||||
<span class="comment">// == Manually submit the consent token to the permit for the permit_success
|
||||
</span><span class="kw">let </span>permit_success = idms_prox_read
|
||||
.check_oauth2_authorise_permit(<span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, <span class="kw-2">&</span>consent_token, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 permit"</span>);
|
||||
|
||||
<span class="comment">// Assert that the consent was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2ConsentGrant(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="comment">// == Submit the token exchange code.
|
||||
</span><span class="kw">let </span>token_req = AccessTokenRequest {
|
||||
grant_type: <span class="string">"authorization_code"</span>.to_string(),
|
||||
code: permit_success.code,
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
client_id: <span class="prelude-val">None</span>,
|
||||
client_secret: <span class="prelude-val">None</span>,
|
||||
<span class="comment">// From the first step.
|
||||
</span>code_verifier,
|
||||
};
|
||||
|
||||
<span class="kw">let </span>token_response = idms_prox_read
|
||||
.check_oauth2_token_exchange(client_authz.as_deref(), <span class="kw-2">&</span>token_req, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 token exchange"</span>);
|
||||
|
||||
<span class="comment">// Assert that the session creation was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2SessionRecord(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="kw">let </span>id_token = token_response.id_token.expect(<span class="string">"No id_token in response!"</span>);
|
||||
<span class="kw">let </span>access_token = token_response.access_token;
|
||||
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>jwkset = idms_prox_read
|
||||
.oauth2_openid_publickey(<span class="string">"test_resource_server"</span>)
|
||||
.expect(<span class="string">"Failed to get public key"</span>);
|
||||
<span class="kw">let </span>public_jwk = jwkset.keys.pop().expect(<span class="string">"no such jwk"</span>);
|
||||
|
||||
<span class="kw">let </span>jws_validator =
|
||||
JwsValidator::try_from(<span class="kw-2">&</span>public_jwk).expect(<span class="string">"failed to build validator"</span>);
|
||||
|
||||
<span class="kw">let </span>oidc_unverified =
|
||||
OidcUnverified::from_str(<span class="kw-2">&</span>id_token).expect(<span class="string">"Failed to parse id_token"</span>);
|
||||
|
||||
<span class="kw">let </span>iat = ct.as_secs() <span class="kw">as </span>i64;
|
||||
|
||||
<span class="kw">let </span>oidc = oidc_unverified
|
||||
.validate(<span class="kw-2">&</span>jws_validator, iat)
|
||||
.expect(<span class="string">"Failed to verify oidc"</span>);
|
||||
|
||||
<span class="comment">// does our id_token contain the expected groups?
|
||||
</span><span class="macro">assert!</span>(oidc.claims.contains_key(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()));
|
||||
|
||||
<span class="macro">assert!</span>(oidc
|
||||
.claims
|
||||
.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
.expect(<span class="string">"unable to find key"</span>)
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.contains(<span class="kw-2">&</span><span class="macro">serde_json::json!</span>(STR_UUID_IDM_ALL_ACCOUNTS)));
|
||||
|
||||
<span class="comment">// Do the id_token details line up to the userinfo?
|
||||
</span><span class="kw">let </span>userinfo = idms_prox_read
|
||||
.oauth2_openid_userinfo(<span class="string">"test_resource_server"</span>, <span class="kw-2">&</span>access_token, ct)
|
||||
.expect(<span class="string">"failed to get userinfo"</span>);
|
||||
|
||||
<span class="comment">// does the userinfo endpoint provide the same groups?
|
||||
</span><span class="macro">assert!</span>(
|
||||
oidc.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
== userinfo.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
<span class="comment">// Check insecure pkce behaviour.
|
||||
</span><span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_insecure_pkce() {
|
||||
|
@ -6776,8 +7178,14 @@
|
|||
</span><span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Even in disable pkce mode, we will allow pkce
|
||||
</span><span class="kw">let </span>_consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>_consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Check we allow none.
|
||||
</span><span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
|
@ -6837,8 +7245,14 @@
|
|||
<span class="comment">// Check that the id_token is signed with the correct key.
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6913,8 +7327,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -6953,8 +7373,14 @@
|
|||
.expect(<span class="string">"Unable to process uat"</span>);
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>_permit_success =
|
||||
|
@ -7117,8 +7543,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -7317,8 +7749,14 @@
|
|||
);
|
||||
|
||||
<span class="comment">// This does have https
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
|
|
@ -4665,7 +4665,7 @@
|
|||
parent_session_id: Uuid,
|
||||
iat: i64,
|
||||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Account>, OperationError> {
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Arc<Entry<EntrySealed, EntryCommitted>>>, OperationError> {
|
||||
<span class="kw">let </span>entry = <span class="self">self</span>.get_qs_txn().internal_search_uuid(uuid).map_err(|e| {
|
||||
<span class="macro">admin_error!</span>(<span class="question-mark">?</span>e, <span class="string">"check_oauth2_account_uuid_valid failed"</span>);
|
||||
e
|
||||
|
@ -4705,7 +4705,7 @@
|
|||
<span class="macro">security_info!</span>(<span class="string">"The token grace window is in effect. Assuming valid."</span>);
|
||||
};
|
||||
|
||||
Account::try_from_entry_no_groups(entry.as_ref()).map(<span class="prelude-val">Some</span>)
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry))
|
||||
}
|
||||
|
||||
<span class="doccomment">/// For any event/operation to proceed, we need to attach an identity to the
|
||||
|
@ -5638,7 +5638,7 @@
|
|||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><AccessTokenResponse, Oauth2Error> {
|
||||
<span class="self">self</span>.oauth2rs
|
||||
.check_oauth2_token_exchange(client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
.check_oauth2_token_exchange(<span class="self">self</span>, client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
}
|
||||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_introspect(
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3682">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3901">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<p>This contains the in memory and loaded set of active oauth2 resource server
|
||||
integrations, which are then able to be used an accessed from the IDM layer
|
||||
for operations involving oauth2 authentication processing.</p>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -938,7 +938,7 @@
|
|||
<span class="attribute">#[instrument(level = <span class="string">"trace"</span>, skip_all)]
|
||||
</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>try_from_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, OperationError> {
|
||||
<span class="kw">let </span>groups = Group::try_from_account_entry_ro(value, qs)<span class="question-mark">?</span>;
|
||||
<span class="macro">try_from_entry!</span>(value, groups)
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>try_from_account_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><Vec<<span class="self">Self</span>>, OperationError> {
|
||||
<span class="macro">try_from_account_e!</span>(value, qs)
|
||||
}
|
||||
|
|
|
@ -3680,6 +3680,225 @@
|
|||
<span id="3680">3680</span>
|
||||
<span id="3681">3681</span>
|
||||
<span id="3682">3682</span>
|
||||
<span id="3683">3683</span>
|
||||
<span id="3684">3684</span>
|
||||
<span id="3685">3685</span>
|
||||
<span id="3686">3686</span>
|
||||
<span id="3687">3687</span>
|
||||
<span id="3688">3688</span>
|
||||
<span id="3689">3689</span>
|
||||
<span id="3690">3690</span>
|
||||
<span id="3691">3691</span>
|
||||
<span id="3692">3692</span>
|
||||
<span id="3693">3693</span>
|
||||
<span id="3694">3694</span>
|
||||
<span id="3695">3695</span>
|
||||
<span id="3696">3696</span>
|
||||
<span id="3697">3697</span>
|
||||
<span id="3698">3698</span>
|
||||
<span id="3699">3699</span>
|
||||
<span id="3700">3700</span>
|
||||
<span id="3701">3701</span>
|
||||
<span id="3702">3702</span>
|
||||
<span id="3703">3703</span>
|
||||
<span id="3704">3704</span>
|
||||
<span id="3705">3705</span>
|
||||
<span id="3706">3706</span>
|
||||
<span id="3707">3707</span>
|
||||
<span id="3708">3708</span>
|
||||
<span id="3709">3709</span>
|
||||
<span id="3710">3710</span>
|
||||
<span id="3711">3711</span>
|
||||
<span id="3712">3712</span>
|
||||
<span id="3713">3713</span>
|
||||
<span id="3714">3714</span>
|
||||
<span id="3715">3715</span>
|
||||
<span id="3716">3716</span>
|
||||
<span id="3717">3717</span>
|
||||
<span id="3718">3718</span>
|
||||
<span id="3719">3719</span>
|
||||
<span id="3720">3720</span>
|
||||
<span id="3721">3721</span>
|
||||
<span id="3722">3722</span>
|
||||
<span id="3723">3723</span>
|
||||
<span id="3724">3724</span>
|
||||
<span id="3725">3725</span>
|
||||
<span id="3726">3726</span>
|
||||
<span id="3727">3727</span>
|
||||
<span id="3728">3728</span>
|
||||
<span id="3729">3729</span>
|
||||
<span id="3730">3730</span>
|
||||
<span id="3731">3731</span>
|
||||
<span id="3732">3732</span>
|
||||
<span id="3733">3733</span>
|
||||
<span id="3734">3734</span>
|
||||
<span id="3735">3735</span>
|
||||
<span id="3736">3736</span>
|
||||
<span id="3737">3737</span>
|
||||
<span id="3738">3738</span>
|
||||
<span id="3739">3739</span>
|
||||
<span id="3740">3740</span>
|
||||
<span id="3741">3741</span>
|
||||
<span id="3742">3742</span>
|
||||
<span id="3743">3743</span>
|
||||
<span id="3744">3744</span>
|
||||
<span id="3745">3745</span>
|
||||
<span id="3746">3746</span>
|
||||
<span id="3747">3747</span>
|
||||
<span id="3748">3748</span>
|
||||
<span id="3749">3749</span>
|
||||
<span id="3750">3750</span>
|
||||
<span id="3751">3751</span>
|
||||
<span id="3752">3752</span>
|
||||
<span id="3753">3753</span>
|
||||
<span id="3754">3754</span>
|
||||
<span id="3755">3755</span>
|
||||
<span id="3756">3756</span>
|
||||
<span id="3757">3757</span>
|
||||
<span id="3758">3758</span>
|
||||
<span id="3759">3759</span>
|
||||
<span id="3760">3760</span>
|
||||
<span id="3761">3761</span>
|
||||
<span id="3762">3762</span>
|
||||
<span id="3763">3763</span>
|
||||
<span id="3764">3764</span>
|
||||
<span id="3765">3765</span>
|
||||
<span id="3766">3766</span>
|
||||
<span id="3767">3767</span>
|
||||
<span id="3768">3768</span>
|
||||
<span id="3769">3769</span>
|
||||
<span id="3770">3770</span>
|
||||
<span id="3771">3771</span>
|
||||
<span id="3772">3772</span>
|
||||
<span id="3773">3773</span>
|
||||
<span id="3774">3774</span>
|
||||
<span id="3775">3775</span>
|
||||
<span id="3776">3776</span>
|
||||
<span id="3777">3777</span>
|
||||
<span id="3778">3778</span>
|
||||
<span id="3779">3779</span>
|
||||
<span id="3780">3780</span>
|
||||
<span id="3781">3781</span>
|
||||
<span id="3782">3782</span>
|
||||
<span id="3783">3783</span>
|
||||
<span id="3784">3784</span>
|
||||
<span id="3785">3785</span>
|
||||
<span id="3786">3786</span>
|
||||
<span id="3787">3787</span>
|
||||
<span id="3788">3788</span>
|
||||
<span id="3789">3789</span>
|
||||
<span id="3790">3790</span>
|
||||
<span id="3791">3791</span>
|
||||
<span id="3792">3792</span>
|
||||
<span id="3793">3793</span>
|
||||
<span id="3794">3794</span>
|
||||
<span id="3795">3795</span>
|
||||
<span id="3796">3796</span>
|
||||
<span id="3797">3797</span>
|
||||
<span id="3798">3798</span>
|
||||
<span id="3799">3799</span>
|
||||
<span id="3800">3800</span>
|
||||
<span id="3801">3801</span>
|
||||
<span id="3802">3802</span>
|
||||
<span id="3803">3803</span>
|
||||
<span id="3804">3804</span>
|
||||
<span id="3805">3805</span>
|
||||
<span id="3806">3806</span>
|
||||
<span id="3807">3807</span>
|
||||
<span id="3808">3808</span>
|
||||
<span id="3809">3809</span>
|
||||
<span id="3810">3810</span>
|
||||
<span id="3811">3811</span>
|
||||
<span id="3812">3812</span>
|
||||
<span id="3813">3813</span>
|
||||
<span id="3814">3814</span>
|
||||
<span id="3815">3815</span>
|
||||
<span id="3816">3816</span>
|
||||
<span id="3817">3817</span>
|
||||
<span id="3818">3818</span>
|
||||
<span id="3819">3819</span>
|
||||
<span id="3820">3820</span>
|
||||
<span id="3821">3821</span>
|
||||
<span id="3822">3822</span>
|
||||
<span id="3823">3823</span>
|
||||
<span id="3824">3824</span>
|
||||
<span id="3825">3825</span>
|
||||
<span id="3826">3826</span>
|
||||
<span id="3827">3827</span>
|
||||
<span id="3828">3828</span>
|
||||
<span id="3829">3829</span>
|
||||
<span id="3830">3830</span>
|
||||
<span id="3831">3831</span>
|
||||
<span id="3832">3832</span>
|
||||
<span id="3833">3833</span>
|
||||
<span id="3834">3834</span>
|
||||
<span id="3835">3835</span>
|
||||
<span id="3836">3836</span>
|
||||
<span id="3837">3837</span>
|
||||
<span id="3838">3838</span>
|
||||
<span id="3839">3839</span>
|
||||
<span id="3840">3840</span>
|
||||
<span id="3841">3841</span>
|
||||
<span id="3842">3842</span>
|
||||
<span id="3843">3843</span>
|
||||
<span id="3844">3844</span>
|
||||
<span id="3845">3845</span>
|
||||
<span id="3846">3846</span>
|
||||
<span id="3847">3847</span>
|
||||
<span id="3848">3848</span>
|
||||
<span id="3849">3849</span>
|
||||
<span id="3850">3850</span>
|
||||
<span id="3851">3851</span>
|
||||
<span id="3852">3852</span>
|
||||
<span id="3853">3853</span>
|
||||
<span id="3854">3854</span>
|
||||
<span id="3855">3855</span>
|
||||
<span id="3856">3856</span>
|
||||
<span id="3857">3857</span>
|
||||
<span id="3858">3858</span>
|
||||
<span id="3859">3859</span>
|
||||
<span id="3860">3860</span>
|
||||
<span id="3861">3861</span>
|
||||
<span id="3862">3862</span>
|
||||
<span id="3863">3863</span>
|
||||
<span id="3864">3864</span>
|
||||
<span id="3865">3865</span>
|
||||
<span id="3866">3866</span>
|
||||
<span id="3867">3867</span>
|
||||
<span id="3868">3868</span>
|
||||
<span id="3869">3869</span>
|
||||
<span id="3870">3870</span>
|
||||
<span id="3871">3871</span>
|
||||
<span id="3872">3872</span>
|
||||
<span id="3873">3873</span>
|
||||
<span id="3874">3874</span>
|
||||
<span id="3875">3875</span>
|
||||
<span id="3876">3876</span>
|
||||
<span id="3877">3877</span>
|
||||
<span id="3878">3878</span>
|
||||
<span id="3879">3879</span>
|
||||
<span id="3880">3880</span>
|
||||
<span id="3881">3881</span>
|
||||
<span id="3882">3882</span>
|
||||
<span id="3883">3883</span>
|
||||
<span id="3884">3884</span>
|
||||
<span id="3885">3885</span>
|
||||
<span id="3886">3886</span>
|
||||
<span id="3887">3887</span>
|
||||
<span id="3888">3888</span>
|
||||
<span id="3889">3889</span>
|
||||
<span id="3890">3890</span>
|
||||
<span id="3891">3891</span>
|
||||
<span id="3892">3892</span>
|
||||
<span id="3893">3893</span>
|
||||
<span id="3894">3894</span>
|
||||
<span id="3895">3895</span>
|
||||
<span id="3896">3896</span>
|
||||
<span id="3897">3897</span>
|
||||
<span id="3898">3898</span>
|
||||
<span id="3899">3899</span>
|
||||
<span id="3900">3900</span>
|
||||
<span id="3901">3901</span>
|
||||
</pre><pre class="rust"><code><span class="doccomment">//! Oauth2 resource server configurations
|
||||
//!
|
||||
//! This contains the in memory and loaded set of active oauth2 resource server
|
||||
|
@ -3716,6 +3935,7 @@
|
|||
<span class="kw">use </span>url::{Origin, Url};
|
||||
|
||||
<span class="kw">use </span><span class="kw">crate</span>::identity::IdentityId;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::account::Account;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::delayed::{DelayedAction, Oauth2ConsentGrant, Oauth2SessionRecord};
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::server::{
|
||||
IdmServerProxyReadTransaction, IdmServerProxyWriteTransaction, IdmServerTransaction,
|
||||
|
@ -4637,6 +4857,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_exchange(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
client_authz: <span class="prelude-ty">Option</span><<span class="kw-2">&</span>str>,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4673,7 +4894,7 @@
|
|||
// TODO: add refresh token grant type.
|
||||
// If it's a refresh token grant, are the consent permissions the same?
|
||||
</span><span class="kw">if </span>token_req.grant_type == <span class="string">"authorization_code" </span>{
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(o2rs, token_req, ct, async_tx)
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(idms, o2rs, token_req, ct, async_tx)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">admin_warn!</span>(<span class="string">"Invalid oauth2 grant_type (should be 'authorization_code')"</span>);
|
||||
<span class="prelude-val">Err</span>(Oauth2Error::InvalidRequest)
|
||||
|
@ -4682,6 +4903,7 @@
|
|||
|
||||
<span class="kw">fn </span>check_oauth2_token_exchange_authorization_code(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
o2rs: <span class="kw-2">&</span>Oauth2RS,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4776,9 +4998,7 @@
|
|||
<span class="prelude-val">Some</span>(code_xchg.scopes.join(<span class="string">" "</span>))
|
||||
};
|
||||
|
||||
<span class="kw">let </span>scope_set: BTreeSet<String> = code_xchg.scopes.iter().cloned().collect();
|
||||
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>scope_set.contains(<span class="string">"openid"</span>) {
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>code_xchg.scopes.contains(<span class="kw-2">&</span><span class="string">"openid"</span>.to_string()) {
|
||||
<span class="comment">// TODO: Scopes map to claims:
|
||||
//
|
||||
// * profile - (name, family\_name, given\_name, middle\_name, nickname, preferred\_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
|
@ -4791,24 +5011,7 @@
|
|||
// TODO: Can the user consent to which claims are released? Today as we don't support most
|
||||
// of them anyway, no, but in the future, we can stash these to the consent req.
|
||||
|
||||
</span><span class="macro">admin_warn!</span>(<span class="string">"prefer_short_username: {:?}"</span>, o2rs.prefer_short_username);
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.name().to_string())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scope_set.contains(<span class="string">"email"</span>) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = code_xchg.uat.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
<span class="comment">// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
|
||||
// amr == auth method
|
||||
</span><span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[code_xchg.uat.auth_type.to_string()]);
|
||||
|
@ -4818,6 +5021,19 @@
|
|||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>idms.qs_read.internal_search_uuid(code_xchg.uat.uuid) {
|
||||
<span class="prelude-val">Ok</span>(entry) => entry,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
|
||||
<span class="kw">let </span>oidc = OidcToken {
|
||||
iss,
|
||||
sub: OidcSubject::U(code_xchg.uat.uuid),
|
||||
|
@ -4832,17 +5048,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(o2rs.name.clone()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(code_xchg.uat.displayname.clone()),
|
||||
<span class="comment">// Map from spn
|
||||
</span>scopes: code_xchg.scopes.clone(),
|
||||
email,
|
||||
email_verified,
|
||||
preferred_username,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
};
|
||||
|
||||
<span class="macro">trace!</span>(<span class="question-mark">?</span>oidc);
|
||||
|
@ -4972,17 +5179,22 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
<span class="string">"access token has account not valid, returning inactive"
|
||||
<span class="string">"access token has no account not valid, returning inactive"
|
||||
</span>);
|
||||
<span class="kw">return </span><span class="prelude-val">Ok</span>(AccessTokenIntrospectResponse::inactive());
|
||||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_no_groups(<span class="kw-2">&</span>entry) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="kw">let </span>scope = <span class="kw">if </span>scopes.is_empty() {
|
||||
|
@ -5064,8 +5276,8 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
|
@ -5075,26 +5287,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn)
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[auth_type.to_string()]);
|
||||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="prelude-val">Ok</span>(OidcToken {
|
||||
|
@ -5111,16 +5315,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(client_id.to_string()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes,
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
})
|
||||
}
|
||||
<span class="comment">// https://openid.net/specs/openid-connect-basic-1_0.html#UserInfoErrorResponse
|
||||
|
@ -5259,6 +5455,47 @@
|
|||
<span class="prelude-val">Ok</span>((client_id.to_string(), secret.to_string()))
|
||||
}
|
||||
|
||||
<span class="kw">fn </span>s_claims_for_account(o2rs: <span class="kw-2">&</span>Oauth2RS, account: <span class="kw-2">&</span>Account, scopes: <span class="kw-2">&</span>[String]) -> OidcClaims {
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name.clone())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = <span class="kw-2">&</span>account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp.clone()), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes: scopes.to_vec(),
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
<span class="kw">fn </span>extra_claims_for_account(
|
||||
account: <span class="kw-2">&</span>Account,
|
||||
scopes: <span class="kw-2">&</span>[String],
|
||||
) -> BTreeMap<String, serde_json::Value> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>extra_claims = BTreeMap::new();
|
||||
<span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()) {
|
||||
extra_claims.insert(
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
account.groups.iter().map(|x| x.to_proto().uuid).collect(),
|
||||
);
|
||||
}
|
||||
<span class="kw">return </span>extra_claims;
|
||||
}
|
||||
|
||||
<span class="attribute">#[cfg(test)]
|
||||
</span><span class="kw">mod </span>tests {
|
||||
<span class="kw">use </span>std::convert::TryFrom;
|
||||
|
@ -5299,7 +5536,8 @@
|
|||
<span class="macro-nonterminal">$ident</span>:expr,
|
||||
<span class="macro-nonterminal">$uat</span>:expr,
|
||||
<span class="macro-nonterminal">$ct</span>:expr,
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr,
|
||||
<span class="macro-nonterminal">$scope</span>:expr
|
||||
) => {{
|
||||
<span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
response_type: <span class="string">"code"</span>.to_string(),
|
||||
|
@ -5310,7 +5548,7 @@
|
|||
code_challenge_method: CodeChallengeMethod::S256,
|
||||
}),
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
scope: <span class="string">"openid"</span>.to_string(),
|
||||
scope: <span class="macro-nonterminal">$scope</span>,
|
||||
nonce: <span class="prelude-val">Some</span>(<span class="string">"abcdef"</span>.to_string()),
|
||||
oidc_ext: Default::default(),
|
||||
unknown_keys: Default::default(),
|
||||
|
@ -5348,7 +5586,7 @@
|
|||
<span class="comment">// System admins
|
||||
</span>(
|
||||
<span class="string">"oauth2_rs_scope_map"</span>,
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"read"</span>.to_string()])
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"groups"</span>.to_string()])
|
||||
.expect(<span class="string">"invalid oauthscope"</span>)
|
||||
),
|
||||
(
|
||||
|
@ -5448,8 +5686,14 @@
|
|||
// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -5702,8 +5946,14 @@
|
|||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -5775,8 +6025,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -5937,8 +6193,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6046,8 +6308,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6221,8 +6489,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6345,8 +6619,14 @@
|
|||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Check reject behaviour
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -6486,8 +6766,8 @@
|
|||
<span class="macro">assert!</span>(
|
||||
discovery.scopes_supported
|
||||
== <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
<span class="string">"openid"</span>.to_string(),
|
||||
<span class="string">"read"</span>.to_string(),
|
||||
<span class="string">"supplement"</span>.to_string(),
|
||||
])
|
||||
);
|
||||
|
@ -6552,8 +6832,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6684,8 +6970,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6760,6 +7052,116 @@
|
|||
)
|
||||
}
|
||||
|
||||
<span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_openid_group_claims() {
|
||||
<span class="macro">run_idm_test!</span>(
|
||||
|_qs: <span class="kw-2">&</span>QueryServer, idms: <span class="kw-2">&</span>IdmServer, idms_delayed: <span class="kw-2">&mut </span>IdmServerDelayed| {
|
||||
<span class="comment">// we run the same test as test_idm_oauth2_openid_extensions()
|
||||
// but change the preferred_username setting on the RS
|
||||
</span><span class="kw">let </span>ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||
<span class="kw">let </span>(secret, uat, ident, <span class="kw">_</span>) =
|
||||
setup_oauth2_resource_server(idms, ct, <span class="bool-val">true</span>, <span class="bool-val">false</span>, <span class="bool-val">true</span>);
|
||||
<span class="kw">let </span>client_authz = <span class="prelude-val">Some</span>(base64::encode(<span class="macro">format!</span>(<span class="string">"test_resource_server:{}"</span>, secret)));
|
||||
|
||||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid groups"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
consent_request
|
||||
{
|
||||
consent_token
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">unreachable!</span>();
|
||||
};
|
||||
|
||||
<span class="comment">// == Manually submit the consent token to the permit for the permit_success
|
||||
</span><span class="kw">let </span>permit_success = idms_prox_read
|
||||
.check_oauth2_authorise_permit(<span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, <span class="kw-2">&</span>consent_token, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 permit"</span>);
|
||||
|
||||
<span class="comment">// Assert that the consent was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2ConsentGrant(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="comment">// == Submit the token exchange code.
|
||||
</span><span class="kw">let </span>token_req = AccessTokenRequest {
|
||||
grant_type: <span class="string">"authorization_code"</span>.to_string(),
|
||||
code: permit_success.code,
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
client_id: <span class="prelude-val">None</span>,
|
||||
client_secret: <span class="prelude-val">None</span>,
|
||||
<span class="comment">// From the first step.
|
||||
</span>code_verifier,
|
||||
};
|
||||
|
||||
<span class="kw">let </span>token_response = idms_prox_read
|
||||
.check_oauth2_token_exchange(client_authz.as_deref(), <span class="kw-2">&</span>token_req, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 token exchange"</span>);
|
||||
|
||||
<span class="comment">// Assert that the session creation was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2SessionRecord(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="kw">let </span>id_token = token_response.id_token.expect(<span class="string">"No id_token in response!"</span>);
|
||||
<span class="kw">let </span>access_token = token_response.access_token;
|
||||
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>jwkset = idms_prox_read
|
||||
.oauth2_openid_publickey(<span class="string">"test_resource_server"</span>)
|
||||
.expect(<span class="string">"Failed to get public key"</span>);
|
||||
<span class="kw">let </span>public_jwk = jwkset.keys.pop().expect(<span class="string">"no such jwk"</span>);
|
||||
|
||||
<span class="kw">let </span>jws_validator =
|
||||
JwsValidator::try_from(<span class="kw-2">&</span>public_jwk).expect(<span class="string">"failed to build validator"</span>);
|
||||
|
||||
<span class="kw">let </span>oidc_unverified =
|
||||
OidcUnverified::from_str(<span class="kw-2">&</span>id_token).expect(<span class="string">"Failed to parse id_token"</span>);
|
||||
|
||||
<span class="kw">let </span>iat = ct.as_secs() <span class="kw">as </span>i64;
|
||||
|
||||
<span class="kw">let </span>oidc = oidc_unverified
|
||||
.validate(<span class="kw-2">&</span>jws_validator, iat)
|
||||
.expect(<span class="string">"Failed to verify oidc"</span>);
|
||||
|
||||
<span class="comment">// does our id_token contain the expected groups?
|
||||
</span><span class="macro">assert!</span>(oidc.claims.contains_key(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()));
|
||||
|
||||
<span class="macro">assert!</span>(oidc
|
||||
.claims
|
||||
.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
.expect(<span class="string">"unable to find key"</span>)
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.contains(<span class="kw-2">&</span><span class="macro">serde_json::json!</span>(STR_UUID_IDM_ALL_ACCOUNTS)));
|
||||
|
||||
<span class="comment">// Do the id_token details line up to the userinfo?
|
||||
</span><span class="kw">let </span>userinfo = idms_prox_read
|
||||
.oauth2_openid_userinfo(<span class="string">"test_resource_server"</span>, <span class="kw-2">&</span>access_token, ct)
|
||||
.expect(<span class="string">"failed to get userinfo"</span>);
|
||||
|
||||
<span class="comment">// does the userinfo endpoint provide the same groups?
|
||||
</span><span class="macro">assert!</span>(
|
||||
oidc.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
== userinfo.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
<span class="comment">// Check insecure pkce behaviour.
|
||||
</span><span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_insecure_pkce() {
|
||||
|
@ -6776,8 +7178,14 @@
|
|||
</span><span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Even in disable pkce mode, we will allow pkce
|
||||
</span><span class="kw">let </span>_consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>_consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Check we allow none.
|
||||
</span><span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
|
@ -6837,8 +7245,14 @@
|
|||
<span class="comment">// Check that the id_token is signed with the correct key.
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6913,8 +7327,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -6953,8 +7373,14 @@
|
|||
.expect(<span class="string">"Unable to process uat"</span>);
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>_permit_success =
|
||||
|
@ -7117,8 +7543,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -7317,8 +7749,14 @@
|
|||
);
|
||||
|
||||
<span class="comment">// This does have https
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
|
|
@ -4665,7 +4665,7 @@
|
|||
parent_session_id: Uuid,
|
||||
iat: i64,
|
||||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Account>, OperationError> {
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Arc<Entry<EntrySealed, EntryCommitted>>>, OperationError> {
|
||||
<span class="kw">let </span>entry = <span class="self">self</span>.get_qs_txn().internal_search_uuid(uuid).map_err(|e| {
|
||||
<span class="macro">admin_error!</span>(<span class="question-mark">?</span>e, <span class="string">"check_oauth2_account_uuid_valid failed"</span>);
|
||||
e
|
||||
|
@ -4705,7 +4705,7 @@
|
|||
<span class="macro">security_info!</span>(<span class="string">"The token grace window is in effect. Assuming valid."</span>);
|
||||
};
|
||||
|
||||
Account::try_from_entry_no_groups(entry.as_ref()).map(<span class="prelude-val">Some</span>)
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry))
|
||||
}
|
||||
|
||||
<span class="doccomment">/// For any event/operation to proceed, we need to attach an identity to the
|
||||
|
@ -5638,7 +5638,7 @@
|
|||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><AccessTokenResponse, Oauth2Error> {
|
||||
<span class="self">self</span>.oauth2rs
|
||||
.check_oauth2_token_exchange(client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
.check_oauth2_token_exchange(<span class="self">self</span>, client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
}
|
||||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_introspect(
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3682">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<!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="Oauth2 resource server configurations"><meta name="keywords" content="rust, rustlang, rust-lang, oauth2"><title>kanidmd_lib::idm::oauth2 - Rust</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" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="../../../kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a><h2 class="location"><a href="#">Module oauth2</a></h2><div class="sidebar-elems"><section><ul class="block"><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li></ul></section></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Module <a href="../../index.html">kanidmd_lib</a>::<wbr><a href="../index.html">idm</a>::<wbr><a class="mod" href="#">oauth2</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../../../clipboard.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="srclink" href="../../../src/kanidmd_lib/idm/oauth2.rs.html#1-3901">source</a> · <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">−</span>]</a></span></div><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Oauth2 resource server configurations</p>
|
||||
<p>This contains the in memory and loaded set of active oauth2 resource server
|
||||
integrations, which are then able to be used an accessed from the IDM layer
|
||||
for operations involving oauth2 authentication processing.</p>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
<!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="Settings of Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc settings</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable Javascript be able to update your settings.</section></noscript><link rel="stylesheet" type="text/css" href="settings.css"><script defer src="settings.js"></script></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="Settings of Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc settings</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Settings</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc settings</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section>You need to enable Javascript be able to update your settings.</section></noscript><link rel="stylesheet" type="text/css" href="settings.css"><script defer src="settings.js"></script></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
|
@ -938,7 +938,7 @@
|
|||
<span class="attribute">#[instrument(level = <span class="string">"trace"</span>, skip_all)]
|
||||
</span><span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn </span>try_from_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="self">Self</span>, OperationError> {
|
||||
<span class="kw">let </span>groups = Group::try_from_account_entry_ro(value, qs)<span class="question-mark">?</span>;
|
||||
<span class="macro">try_from_entry!</span>(value, groups)
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>try_from_account_entry_ro(
|
||||
value: <span class="kw-2">&</span>Entry<EntrySealed, EntryCommitted>,
|
||||
qs: <span class="kw-2">&mut </span>QueryServerReadTransaction,
|
||||
qs: <span class="kw-2">&</span>QueryServerReadTransaction,
|
||||
) -> <span class="prelude-ty">Result</span><Vec<<span class="self">Self</span>>, OperationError> {
|
||||
<span class="macro">try_from_account_e!</span>(value, qs)
|
||||
}
|
||||
|
|
|
@ -3680,6 +3680,225 @@
|
|||
<span id="3680">3680</span>
|
||||
<span id="3681">3681</span>
|
||||
<span id="3682">3682</span>
|
||||
<span id="3683">3683</span>
|
||||
<span id="3684">3684</span>
|
||||
<span id="3685">3685</span>
|
||||
<span id="3686">3686</span>
|
||||
<span id="3687">3687</span>
|
||||
<span id="3688">3688</span>
|
||||
<span id="3689">3689</span>
|
||||
<span id="3690">3690</span>
|
||||
<span id="3691">3691</span>
|
||||
<span id="3692">3692</span>
|
||||
<span id="3693">3693</span>
|
||||
<span id="3694">3694</span>
|
||||
<span id="3695">3695</span>
|
||||
<span id="3696">3696</span>
|
||||
<span id="3697">3697</span>
|
||||
<span id="3698">3698</span>
|
||||
<span id="3699">3699</span>
|
||||
<span id="3700">3700</span>
|
||||
<span id="3701">3701</span>
|
||||
<span id="3702">3702</span>
|
||||
<span id="3703">3703</span>
|
||||
<span id="3704">3704</span>
|
||||
<span id="3705">3705</span>
|
||||
<span id="3706">3706</span>
|
||||
<span id="3707">3707</span>
|
||||
<span id="3708">3708</span>
|
||||
<span id="3709">3709</span>
|
||||
<span id="3710">3710</span>
|
||||
<span id="3711">3711</span>
|
||||
<span id="3712">3712</span>
|
||||
<span id="3713">3713</span>
|
||||
<span id="3714">3714</span>
|
||||
<span id="3715">3715</span>
|
||||
<span id="3716">3716</span>
|
||||
<span id="3717">3717</span>
|
||||
<span id="3718">3718</span>
|
||||
<span id="3719">3719</span>
|
||||
<span id="3720">3720</span>
|
||||
<span id="3721">3721</span>
|
||||
<span id="3722">3722</span>
|
||||
<span id="3723">3723</span>
|
||||
<span id="3724">3724</span>
|
||||
<span id="3725">3725</span>
|
||||
<span id="3726">3726</span>
|
||||
<span id="3727">3727</span>
|
||||
<span id="3728">3728</span>
|
||||
<span id="3729">3729</span>
|
||||
<span id="3730">3730</span>
|
||||
<span id="3731">3731</span>
|
||||
<span id="3732">3732</span>
|
||||
<span id="3733">3733</span>
|
||||
<span id="3734">3734</span>
|
||||
<span id="3735">3735</span>
|
||||
<span id="3736">3736</span>
|
||||
<span id="3737">3737</span>
|
||||
<span id="3738">3738</span>
|
||||
<span id="3739">3739</span>
|
||||
<span id="3740">3740</span>
|
||||
<span id="3741">3741</span>
|
||||
<span id="3742">3742</span>
|
||||
<span id="3743">3743</span>
|
||||
<span id="3744">3744</span>
|
||||
<span id="3745">3745</span>
|
||||
<span id="3746">3746</span>
|
||||
<span id="3747">3747</span>
|
||||
<span id="3748">3748</span>
|
||||
<span id="3749">3749</span>
|
||||
<span id="3750">3750</span>
|
||||
<span id="3751">3751</span>
|
||||
<span id="3752">3752</span>
|
||||
<span id="3753">3753</span>
|
||||
<span id="3754">3754</span>
|
||||
<span id="3755">3755</span>
|
||||
<span id="3756">3756</span>
|
||||
<span id="3757">3757</span>
|
||||
<span id="3758">3758</span>
|
||||
<span id="3759">3759</span>
|
||||
<span id="3760">3760</span>
|
||||
<span id="3761">3761</span>
|
||||
<span id="3762">3762</span>
|
||||
<span id="3763">3763</span>
|
||||
<span id="3764">3764</span>
|
||||
<span id="3765">3765</span>
|
||||
<span id="3766">3766</span>
|
||||
<span id="3767">3767</span>
|
||||
<span id="3768">3768</span>
|
||||
<span id="3769">3769</span>
|
||||
<span id="3770">3770</span>
|
||||
<span id="3771">3771</span>
|
||||
<span id="3772">3772</span>
|
||||
<span id="3773">3773</span>
|
||||
<span id="3774">3774</span>
|
||||
<span id="3775">3775</span>
|
||||
<span id="3776">3776</span>
|
||||
<span id="3777">3777</span>
|
||||
<span id="3778">3778</span>
|
||||
<span id="3779">3779</span>
|
||||
<span id="3780">3780</span>
|
||||
<span id="3781">3781</span>
|
||||
<span id="3782">3782</span>
|
||||
<span id="3783">3783</span>
|
||||
<span id="3784">3784</span>
|
||||
<span id="3785">3785</span>
|
||||
<span id="3786">3786</span>
|
||||
<span id="3787">3787</span>
|
||||
<span id="3788">3788</span>
|
||||
<span id="3789">3789</span>
|
||||
<span id="3790">3790</span>
|
||||
<span id="3791">3791</span>
|
||||
<span id="3792">3792</span>
|
||||
<span id="3793">3793</span>
|
||||
<span id="3794">3794</span>
|
||||
<span id="3795">3795</span>
|
||||
<span id="3796">3796</span>
|
||||
<span id="3797">3797</span>
|
||||
<span id="3798">3798</span>
|
||||
<span id="3799">3799</span>
|
||||
<span id="3800">3800</span>
|
||||
<span id="3801">3801</span>
|
||||
<span id="3802">3802</span>
|
||||
<span id="3803">3803</span>
|
||||
<span id="3804">3804</span>
|
||||
<span id="3805">3805</span>
|
||||
<span id="3806">3806</span>
|
||||
<span id="3807">3807</span>
|
||||
<span id="3808">3808</span>
|
||||
<span id="3809">3809</span>
|
||||
<span id="3810">3810</span>
|
||||
<span id="3811">3811</span>
|
||||
<span id="3812">3812</span>
|
||||
<span id="3813">3813</span>
|
||||
<span id="3814">3814</span>
|
||||
<span id="3815">3815</span>
|
||||
<span id="3816">3816</span>
|
||||
<span id="3817">3817</span>
|
||||
<span id="3818">3818</span>
|
||||
<span id="3819">3819</span>
|
||||
<span id="3820">3820</span>
|
||||
<span id="3821">3821</span>
|
||||
<span id="3822">3822</span>
|
||||
<span id="3823">3823</span>
|
||||
<span id="3824">3824</span>
|
||||
<span id="3825">3825</span>
|
||||
<span id="3826">3826</span>
|
||||
<span id="3827">3827</span>
|
||||
<span id="3828">3828</span>
|
||||
<span id="3829">3829</span>
|
||||
<span id="3830">3830</span>
|
||||
<span id="3831">3831</span>
|
||||
<span id="3832">3832</span>
|
||||
<span id="3833">3833</span>
|
||||
<span id="3834">3834</span>
|
||||
<span id="3835">3835</span>
|
||||
<span id="3836">3836</span>
|
||||
<span id="3837">3837</span>
|
||||
<span id="3838">3838</span>
|
||||
<span id="3839">3839</span>
|
||||
<span id="3840">3840</span>
|
||||
<span id="3841">3841</span>
|
||||
<span id="3842">3842</span>
|
||||
<span id="3843">3843</span>
|
||||
<span id="3844">3844</span>
|
||||
<span id="3845">3845</span>
|
||||
<span id="3846">3846</span>
|
||||
<span id="3847">3847</span>
|
||||
<span id="3848">3848</span>
|
||||
<span id="3849">3849</span>
|
||||
<span id="3850">3850</span>
|
||||
<span id="3851">3851</span>
|
||||
<span id="3852">3852</span>
|
||||
<span id="3853">3853</span>
|
||||
<span id="3854">3854</span>
|
||||
<span id="3855">3855</span>
|
||||
<span id="3856">3856</span>
|
||||
<span id="3857">3857</span>
|
||||
<span id="3858">3858</span>
|
||||
<span id="3859">3859</span>
|
||||
<span id="3860">3860</span>
|
||||
<span id="3861">3861</span>
|
||||
<span id="3862">3862</span>
|
||||
<span id="3863">3863</span>
|
||||
<span id="3864">3864</span>
|
||||
<span id="3865">3865</span>
|
||||
<span id="3866">3866</span>
|
||||
<span id="3867">3867</span>
|
||||
<span id="3868">3868</span>
|
||||
<span id="3869">3869</span>
|
||||
<span id="3870">3870</span>
|
||||
<span id="3871">3871</span>
|
||||
<span id="3872">3872</span>
|
||||
<span id="3873">3873</span>
|
||||
<span id="3874">3874</span>
|
||||
<span id="3875">3875</span>
|
||||
<span id="3876">3876</span>
|
||||
<span id="3877">3877</span>
|
||||
<span id="3878">3878</span>
|
||||
<span id="3879">3879</span>
|
||||
<span id="3880">3880</span>
|
||||
<span id="3881">3881</span>
|
||||
<span id="3882">3882</span>
|
||||
<span id="3883">3883</span>
|
||||
<span id="3884">3884</span>
|
||||
<span id="3885">3885</span>
|
||||
<span id="3886">3886</span>
|
||||
<span id="3887">3887</span>
|
||||
<span id="3888">3888</span>
|
||||
<span id="3889">3889</span>
|
||||
<span id="3890">3890</span>
|
||||
<span id="3891">3891</span>
|
||||
<span id="3892">3892</span>
|
||||
<span id="3893">3893</span>
|
||||
<span id="3894">3894</span>
|
||||
<span id="3895">3895</span>
|
||||
<span id="3896">3896</span>
|
||||
<span id="3897">3897</span>
|
||||
<span id="3898">3898</span>
|
||||
<span id="3899">3899</span>
|
||||
<span id="3900">3900</span>
|
||||
<span id="3901">3901</span>
|
||||
</pre><pre class="rust"><code><span class="doccomment">//! Oauth2 resource server configurations
|
||||
//!
|
||||
//! This contains the in memory and loaded set of active oauth2 resource server
|
||||
|
@ -3716,6 +3935,7 @@
|
|||
<span class="kw">use </span>url::{Origin, Url};
|
||||
|
||||
<span class="kw">use </span><span class="kw">crate</span>::identity::IdentityId;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::account::Account;
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::delayed::{DelayedAction, Oauth2ConsentGrant, Oauth2SessionRecord};
|
||||
<span class="kw">use </span><span class="kw">crate</span>::idm::server::{
|
||||
IdmServerProxyReadTransaction, IdmServerProxyWriteTransaction, IdmServerTransaction,
|
||||
|
@ -4637,6 +4857,7 @@
|
|||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_exchange(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
client_authz: <span class="prelude-ty">Option</span><<span class="kw-2">&</span>str>,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4673,7 +4894,7 @@
|
|||
// TODO: add refresh token grant type.
|
||||
// If it's a refresh token grant, are the consent permissions the same?
|
||||
</span><span class="kw">if </span>token_req.grant_type == <span class="string">"authorization_code" </span>{
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(o2rs, token_req, ct, async_tx)
|
||||
<span class="self">self</span>.check_oauth2_token_exchange_authorization_code(idms, o2rs, token_req, ct, async_tx)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">admin_warn!</span>(<span class="string">"Invalid oauth2 grant_type (should be 'authorization_code')"</span>);
|
||||
<span class="prelude-val">Err</span>(Oauth2Error::InvalidRequest)
|
||||
|
@ -4682,6 +4903,7 @@
|
|||
|
||||
<span class="kw">fn </span>check_oauth2_token_exchange_authorization_code(
|
||||
<span class="kw-2">&</span><span class="self">self</span>,
|
||||
idms: <span class="kw-2">&</span>IdmServerProxyReadTransaction<<span class="lifetime">'_</span>>,
|
||||
o2rs: <span class="kw-2">&</span>Oauth2RS,
|
||||
token_req: <span class="kw-2">&</span>AccessTokenRequest,
|
||||
ct: Duration,
|
||||
|
@ -4776,9 +4998,7 @@
|
|||
<span class="prelude-val">Some</span>(code_xchg.scopes.join(<span class="string">" "</span>))
|
||||
};
|
||||
|
||||
<span class="kw">let </span>scope_set: BTreeSet<String> = code_xchg.scopes.iter().cloned().collect();
|
||||
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>scope_set.contains(<span class="string">"openid"</span>) {
|
||||
<span class="kw">let </span>id_token = <span class="kw">if </span>code_xchg.scopes.contains(<span class="kw-2">&</span><span class="string">"openid"</span>.to_string()) {
|
||||
<span class="comment">// TODO: Scopes map to claims:
|
||||
//
|
||||
// * profile - (name, family\_name, given\_name, middle\_name, nickname, preferred\_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
|
@ -4791,24 +5011,7 @@
|
|||
// TODO: Can the user consent to which claims are released? Today as we don't support most
|
||||
// of them anyway, no, but in the future, we can stash these to the consent req.
|
||||
|
||||
</span><span class="macro">admin_warn!</span>(<span class="string">"prefer_short_username: {:?}"</span>, o2rs.prefer_short_username);
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.name().to_string())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(code_xchg.uat.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scope_set.contains(<span class="string">"email"</span>) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = code_xchg.uat.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
<span class="comment">// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
// TODO: If max_age was requested in the request, we MUST provide auth_time.
|
||||
|
||||
// amr == auth method
|
||||
</span><span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[code_xchg.uat.auth_type.to_string()]);
|
||||
|
@ -4818,6 +5021,19 @@
|
|||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>idms.qs_read.internal_search_uuid(code_xchg.uat.uuid) {
|
||||
<span class="prelude-val">Ok</span>(entry) => entry,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>code_xchg.scopes);
|
||||
|
||||
<span class="kw">let </span>oidc = OidcToken {
|
||||
iss,
|
||||
sub: OidcSubject::U(code_xchg.uat.uuid),
|
||||
|
@ -4832,17 +5048,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(o2rs.name.clone()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(code_xchg.uat.displayname.clone()),
|
||||
<span class="comment">// Map from spn
|
||||
</span>scopes: code_xchg.scopes.clone(),
|
||||
email,
|
||||
email_verified,
|
||||
preferred_username,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
};
|
||||
|
||||
<span class="macro">trace!</span>(<span class="question-mark">?</span>oidc);
|
||||
|
@ -4972,17 +5179,22 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
<span class="string">"access token has account not valid, returning inactive"
|
||||
<span class="string">"access token has no account not valid, returning inactive"
|
||||
</span>);
|
||||
<span class="kw">return </span><span class="prelude-val">Ok</span>(AccessTokenIntrospectResponse::inactive());
|
||||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_no_groups(<span class="kw-2">&</span>entry) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="kw">let </span>scope = <span class="kw">if </span>scopes.is_empty() {
|
||||
|
@ -5064,8 +5276,8 @@
|
|||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||
.map_err(|<span class="kw">_</span>| <span class="macro">admin_error!</span>(<span class="string">"Account is not valid"</span>));
|
||||
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(account)) => account,
|
||||
<span class="kw">let </span>entry = <span class="kw">match </span>valid {
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry)) => entry,
|
||||
<span class="kw">_ </span>=> {
|
||||
<span class="macro">security_info!</span>(
|
||||
<span class="question-mark">?</span>uuid,
|
||||
|
@ -5075,26 +5287,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn)
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
<span class="kw">let </span>account = <span class="kw">match </span>Account::try_from_entry_ro(<span class="kw-2">&</span>entry, <span class="kw-2">&</span>idms.qs_read) {
|
||||
<span class="prelude-val">Ok</span>(account) => account,
|
||||
<span class="prelude-val">Err</span>(err) => <span class="kw">return </span><span class="prelude-val">Err</span>(Oauth2Error::ServerError(err)),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>amr = <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[auth_type.to_string()]);
|
||||
|
||||
<span class="kw">let </span>iss = o2rs.iss.clone();
|
||||
|
||||
<span class="kw">let </span>s_claims = s_claims_for_account(o2rs, <span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
<span class="kw">let </span>extra_claims = extra_claims_for_account(<span class="kw-2">&</span>account, <span class="kw-2">&</span>scopes);
|
||||
|
||||
<span class="comment">// ==== good to generate response ====
|
||||
|
||||
</span><span class="prelude-val">Ok</span>(OidcToken {
|
||||
|
@ -5111,16 +5315,8 @@
|
|||
amr,
|
||||
azp: <span class="prelude-val">Some</span>(client_id.to_string()),
|
||||
jti: <span class="prelude-val">None</span>,
|
||||
s_claims: OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes,
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
},
|
||||
claims: Default::default(),
|
||||
s_claims,
|
||||
claims: extra_claims,
|
||||
})
|
||||
}
|
||||
<span class="comment">// https://openid.net/specs/openid-connect-basic-1_0.html#UserInfoErrorResponse
|
||||
|
@ -5259,6 +5455,47 @@
|
|||
<span class="prelude-val">Ok</span>((client_id.to_string(), secret.to_string()))
|
||||
}
|
||||
|
||||
<span class="kw">fn </span>s_claims_for_account(o2rs: <span class="kw-2">&</span>Oauth2RS, account: <span class="kw-2">&</span>Account, scopes: <span class="kw-2">&</span>[String]) -> OidcClaims {
|
||||
<span class="kw">let </span>preferred_username = <span class="kw">if </span>o2rs.prefer_short_username {
|
||||
<span class="prelude-val">Some</span>(account.name.clone())
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Some</span>(account.spn.clone())
|
||||
};
|
||||
|
||||
<span class="kw">let </span>(email, email_verified) = <span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"email"</span>.to_string()) {
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(mp) = <span class="kw-2">&</span>account.mail_primary {
|
||||
(<span class="prelude-val">Some</span>(mp.clone()), <span class="prelude-val">Some</span>(<span class="bool-val">true</span>))
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
}
|
||||
} <span class="kw">else </span>{
|
||||
(<span class="prelude-val">None</span>, <span class="prelude-val">None</span>)
|
||||
};
|
||||
|
||||
OidcClaims {
|
||||
<span class="comment">// Map from displayname
|
||||
</span>name: <span class="prelude-val">Some</span>(account.displayname.clone()),
|
||||
scopes: scopes.to_vec(),
|
||||
preferred_username,
|
||||
email,
|
||||
email_verified,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
<span class="kw">fn </span>extra_claims_for_account(
|
||||
account: <span class="kw-2">&</span>Account,
|
||||
scopes: <span class="kw-2">&</span>[String],
|
||||
) -> BTreeMap<String, serde_json::Value> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>extra_claims = BTreeMap::new();
|
||||
<span class="kw">if </span>scopes.contains(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()) {
|
||||
extra_claims.insert(
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
account.groups.iter().map(|x| x.to_proto().uuid).collect(),
|
||||
);
|
||||
}
|
||||
<span class="kw">return </span>extra_claims;
|
||||
}
|
||||
|
||||
<span class="attribute">#[cfg(test)]
|
||||
</span><span class="kw">mod </span>tests {
|
||||
<span class="kw">use </span>std::convert::TryFrom;
|
||||
|
@ -5299,7 +5536,8 @@
|
|||
<span class="macro-nonterminal">$ident</span>:expr,
|
||||
<span class="macro-nonterminal">$uat</span>:expr,
|
||||
<span class="macro-nonterminal">$ct</span>:expr,
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr
|
||||
<span class="macro-nonterminal">$code_challenge</span>:expr,
|
||||
<span class="macro-nonterminal">$scope</span>:expr
|
||||
) => {{
|
||||
<span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
response_type: <span class="string">"code"</span>.to_string(),
|
||||
|
@ -5310,7 +5548,7 @@
|
|||
code_challenge_method: CodeChallengeMethod::S256,
|
||||
}),
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
scope: <span class="string">"openid"</span>.to_string(),
|
||||
scope: <span class="macro-nonterminal">$scope</span>,
|
||||
nonce: <span class="prelude-val">Some</span>(<span class="string">"abcdef"</span>.to_string()),
|
||||
oidc_ext: Default::default(),
|
||||
unknown_keys: Default::default(),
|
||||
|
@ -5348,7 +5586,7 @@
|
|||
<span class="comment">// System admins
|
||||
</span>(
|
||||
<span class="string">"oauth2_rs_scope_map"</span>,
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"read"</span>.to_string()])
|
||||
Value::new_oauthscopemap(UUID_SYSTEM_ADMINS, <span class="macro">btreeset!</span>[<span class="string">"groups"</span>.to_string()])
|
||||
.expect(<span class="string">"invalid oauthscope"</span>)
|
||||
),
|
||||
(
|
||||
|
@ -5448,8 +5686,14 @@
|
|||
// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -5702,8 +5946,14 @@
|
|||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -5775,8 +6025,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -5937,8 +6193,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6046,8 +6308,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6221,8 +6489,14 @@
|
|||
|
||||
<span class="comment">// == Setup the authorisation request
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6345,8 +6619,14 @@
|
|||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Check reject behaviour
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token = <span class="kw">if let </span>AuthoriseResponse::ConsentRequested {
|
||||
consent_token, ..
|
||||
|
@ -6486,8 +6766,8 @@
|
|||
<span class="macro">assert!</span>(
|
||||
discovery.scopes_supported
|
||||
== <span class="prelude-val">Some</span>(<span class="macro">vec!</span>[
|
||||
<span class="string">"groups"</span>.to_string(),
|
||||
<span class="string">"openid"</span>.to_string(),
|
||||
<span class="string">"read"</span>.to_string(),
|
||||
<span class="string">"supplement"</span>.to_string(),
|
||||
])
|
||||
);
|
||||
|
@ -6552,8 +6832,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6684,8 +6970,14 @@
|
|||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6760,6 +7052,116 @@
|
|||
)
|
||||
}
|
||||
|
||||
<span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_openid_group_claims() {
|
||||
<span class="macro">run_idm_test!</span>(
|
||||
|_qs: <span class="kw-2">&</span>QueryServer, idms: <span class="kw-2">&</span>IdmServer, idms_delayed: <span class="kw-2">&mut </span>IdmServerDelayed| {
|
||||
<span class="comment">// we run the same test as test_idm_oauth2_openid_extensions()
|
||||
// but change the preferred_username setting on the RS
|
||||
</span><span class="kw">let </span>ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||
<span class="kw">let </span>(secret, uat, ident, <span class="kw">_</span>) =
|
||||
setup_oauth2_resource_server(idms, ct, <span class="bool-val">true</span>, <span class="bool-val">false</span>, <span class="bool-val">true</span>);
|
||||
<span class="kw">let </span>client_authz = <span class="prelude-val">Some</span>(base64::encode(<span class="macro">format!</span>(<span class="string">"test_resource_server:{}"</span>, secret)));
|
||||
|
||||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid groups"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
consent_request
|
||||
{
|
||||
consent_token
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">unreachable!</span>();
|
||||
};
|
||||
|
||||
<span class="comment">// == Manually submit the consent token to the permit for the permit_success
|
||||
</span><span class="kw">let </span>permit_success = idms_prox_read
|
||||
.check_oauth2_authorise_permit(<span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, <span class="kw-2">&</span>consent_token, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 permit"</span>);
|
||||
|
||||
<span class="comment">// Assert that the consent was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2ConsentGrant(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="comment">// == Submit the token exchange code.
|
||||
</span><span class="kw">let </span>token_req = AccessTokenRequest {
|
||||
grant_type: <span class="string">"authorization_code"</span>.to_string(),
|
||||
code: permit_success.code,
|
||||
redirect_uri: Url::parse(<span class="string">"https://demo.example.com/oauth2/result"</span>).unwrap(),
|
||||
client_id: <span class="prelude-val">None</span>,
|
||||
client_secret: <span class="prelude-val">None</span>,
|
||||
<span class="comment">// From the first step.
|
||||
</span>code_verifier,
|
||||
};
|
||||
|
||||
<span class="kw">let </span>token_response = idms_prox_read
|
||||
.check_oauth2_token_exchange(client_authz.as_deref(), <span class="kw-2">&</span>token_req, ct)
|
||||
.expect(<span class="string">"Failed to perform oauth2 token exchange"</span>);
|
||||
|
||||
<span class="comment">// Assert that the session creation was submitted
|
||||
</span><span class="kw">match </span>idms_delayed.async_rx.blocking_recv() {
|
||||
<span class="prelude-val">Some</span>(DelayedAction::Oauth2SessionRecord(<span class="kw">_</span>)) => {}
|
||||
<span class="kw">_ </span>=> <span class="macro">assert!</span>(<span class="bool-val">false</span>),
|
||||
}
|
||||
|
||||
<span class="kw">let </span>id_token = token_response.id_token.expect(<span class="string">"No id_token in response!"</span>);
|
||||
<span class="kw">let </span>access_token = token_response.access_token;
|
||||
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>jwkset = idms_prox_read
|
||||
.oauth2_openid_publickey(<span class="string">"test_resource_server"</span>)
|
||||
.expect(<span class="string">"Failed to get public key"</span>);
|
||||
<span class="kw">let </span>public_jwk = jwkset.keys.pop().expect(<span class="string">"no such jwk"</span>);
|
||||
|
||||
<span class="kw">let </span>jws_validator =
|
||||
JwsValidator::try_from(<span class="kw-2">&</span>public_jwk).expect(<span class="string">"failed to build validator"</span>);
|
||||
|
||||
<span class="kw">let </span>oidc_unverified =
|
||||
OidcUnverified::from_str(<span class="kw-2">&</span>id_token).expect(<span class="string">"Failed to parse id_token"</span>);
|
||||
|
||||
<span class="kw">let </span>iat = ct.as_secs() <span class="kw">as </span>i64;
|
||||
|
||||
<span class="kw">let </span>oidc = oidc_unverified
|
||||
.validate(<span class="kw-2">&</span>jws_validator, iat)
|
||||
.expect(<span class="string">"Failed to verify oidc"</span>);
|
||||
|
||||
<span class="comment">// does our id_token contain the expected groups?
|
||||
</span><span class="macro">assert!</span>(oidc.claims.contains_key(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string()));
|
||||
|
||||
<span class="macro">assert!</span>(oidc
|
||||
.claims
|
||||
.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
.expect(<span class="string">"unable to find key"</span>)
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.contains(<span class="kw-2">&</span><span class="macro">serde_json::json!</span>(STR_UUID_IDM_ALL_ACCOUNTS)));
|
||||
|
||||
<span class="comment">// Do the id_token details line up to the userinfo?
|
||||
</span><span class="kw">let </span>userinfo = idms_prox_read
|
||||
.oauth2_openid_userinfo(<span class="string">"test_resource_server"</span>, <span class="kw-2">&</span>access_token, ct)
|
||||
.expect(<span class="string">"failed to get userinfo"</span>);
|
||||
|
||||
<span class="comment">// does the userinfo endpoint provide the same groups?
|
||||
</span><span class="macro">assert!</span>(
|
||||
oidc.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
== userinfo.claims.get(<span class="kw-2">&</span><span class="string">"groups"</span>.to_string())
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
<span class="comment">// Check insecure pkce behaviour.
|
||||
</span><span class="attribute">#[test]
|
||||
</span><span class="kw">fn </span>test_idm_oauth2_insecure_pkce() {
|
||||
|
@ -6776,8 +7178,14 @@
|
|||
</span><span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="comment">// Even in disable pkce mode, we will allow pkce
|
||||
</span><span class="kw">let </span>_consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>_consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Check we allow none.
|
||||
</span><span class="kw">let </span>auth_req = AuthorisationRequest {
|
||||
|
@ -6837,8 +7245,14 @@
|
|||
<span class="comment">// Check that the id_token is signed with the correct key.
|
||||
</span><span class="kw">let </span>(code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="kw">let </span>consent_token =
|
||||
<span class="kw">if let </span>AuthoriseResponse::ConsentRequested { consent_token, .. } =
|
||||
|
@ -6913,8 +7327,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -6953,8 +7373,14 @@
|
|||
.expect(<span class="string">"Unable to process uat"</span>);
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>_permit_success =
|
||||
|
@ -7117,8 +7543,14 @@
|
|||
<span class="kw">let </span>idms_prox_read = task::block_on(idms.proxy_read());
|
||||
|
||||
<span class="kw">let </span>(_code_verifier, code_challenge) = <span class="macro">create_code_verifier!</span>(<span class="string">"Whar Garble"</span>);
|
||||
<span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
<span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
@ -7317,8 +7749,14 @@
|
|||
);
|
||||
|
||||
<span class="comment">// This does have https
|
||||
</span><span class="kw">let </span>consent_request =
|
||||
<span class="macro">good_authorisation_request!</span>(idms_prox_read, <span class="kw-2">&</span>ident, <span class="kw-2">&</span>uat, ct, code_challenge);
|
||||
</span><span class="kw">let </span>consent_request = <span class="macro">good_authorisation_request!</span>(
|
||||
idms_prox_read,
|
||||
<span class="kw-2">&</span>ident,
|
||||
<span class="kw-2">&</span>uat,
|
||||
ct,
|
||||
code_challenge,
|
||||
<span class="string">"openid"</span>.to_string()
|
||||
);
|
||||
|
||||
<span class="comment">// Should be in the consent phase;
|
||||
</span><span class="kw">let </span>consent_token =
|
||||
|
|
|
@ -4665,7 +4665,7 @@
|
|||
parent_session_id: Uuid,
|
||||
iat: i64,
|
||||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Account>, OperationError> {
|
||||
) -> <span class="prelude-ty">Result</span><<span class="prelude-ty">Option</span><Arc<Entry<EntrySealed, EntryCommitted>>>, OperationError> {
|
||||
<span class="kw">let </span>entry = <span class="self">self</span>.get_qs_txn().internal_search_uuid(uuid).map_err(|e| {
|
||||
<span class="macro">admin_error!</span>(<span class="question-mark">?</span>e, <span class="string">"check_oauth2_account_uuid_valid failed"</span>);
|
||||
e
|
||||
|
@ -4705,7 +4705,7 @@
|
|||
<span class="macro">security_info!</span>(<span class="string">"The token grace window is in effect. Assuming valid."</span>);
|
||||
};
|
||||
|
||||
Account::try_from_entry_no_groups(entry.as_ref()).map(<span class="prelude-val">Some</span>)
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(entry))
|
||||
}
|
||||
|
||||
<span class="doccomment">/// For any event/operation to proceed, we need to attach an identity to the
|
||||
|
@ -5638,7 +5638,7 @@
|
|||
ct: Duration,
|
||||
) -> <span class="prelude-ty">Result</span><AccessTokenResponse, Oauth2Error> {
|
||||
<span class="self">self</span>.oauth2rs
|
||||
.check_oauth2_token_exchange(client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
.check_oauth2_token_exchange(<span class="self">self</span>, client_authz, token_req, ct, <span class="kw-2">&</span><span class="self">self</span>.async_tx)
|
||||
}
|
||||
|
||||
<span class="kw">pub fn </span>check_oauth2_token_introspect(
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidmd_lib/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidmd_lib" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
||||
<!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="Documentation for Rustdoc"><meta name="keywords" content="rust, rustlang, rust-lang"><title>Rustdoc help</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" href="./normalize.css"><link rel="stylesheet" href="./rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="./ayu.css" disabled><link rel="stylesheet" href="./dark.css" disabled><link rel="stylesheet" href="./light.css" id="themeStyle"><script id="default-settings" ></script><script src="./storage.js"></script><script defer src="./main.js"></script><noscript><link rel="stylesheet" href="./noscript.css"></noscript><link rel="alternate icon" type="image/png" href="./favicon-16x16.png"><link rel="alternate icon" type="image/png" href="./favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="./favicon.svg"></head><body class="rustdoc mod"><!--[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">☰</button><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2></h2></nav><nav class="sidebar"><a class="sidebar-logo" href="./kanidm_proto/index.html"><div class="logo-container"><img class="rust-logo" src="./rust-logo.svg" alt="logo"></div></a><h2 class="location">Help</h2><div class="sidebar-elems"></div></nav><main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="./help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="./settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="./wheel.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1 class="fqn">Rustdoc help</h1><span class="out-of-band"><a id="back" href="javascript:void(0)" onclick="history.back();">Back</a></span></div><noscript><section><p>You need to enable Javascript to use keyboard commands or search.</p><p>For more information, browse the <a href="https://doc.rust-lang.org/rustdoc/">rustdoc handbook</a>.</p></section></noscript></section></div></main><div id="rustdoc-vars" data-root-path="./" data-current-crate="kanidm_proto" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0 (69f9c33d7 2022-12-12)" ></div></body></html>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue