Deploying to gh-pages from @ a73725eb39 🚀

This commit is contained in:
realaravinth
2021-03-11 10:13:22 +00:00
parent af8eb6983b
commit ed5442414c
51 changed files with 798 additions and 146 deletions

View File

@@ -236,6 +236,21 @@
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
</pre><div class="example-wrap"><pre class="rust ">
<span class="comment">/*
* Copyright (C) 2021 Aravinth Manivannan &lt;realaravinth@batsense.net&gt;
@@ -262,11 +277,6 @@
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">errors</span>::<span class="kw-2">*</span>;
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">Data</span>;
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>, <span class="ident">Deserialize</span>, <span class="ident">Serialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">SomeData</span> {
<span class="kw">pub</span> <span class="ident">a</span>: <span class="ident">String</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>, <span class="ident">Deserialize</span>, <span class="ident">Serialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Register</span> {
<span class="kw">pub</span> <span class="ident">username</span>: <span class="ident">String</span>,
@@ -343,16 +353,55 @@
<span class="ident">HttpResponse</span>::<span class="prelude-val">Ok</span>()
}
<span class="kw">fn</span> <span class="ident">is_authenticated</span>(<span class="ident">id</span>: <span class="kw-2">&amp;</span><span class="ident">Identity</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="ident">bool</span><span class="op">&gt;</span> {
<span class="macro">debug</span><span class="macro">!</span>(<span class="string">&quot;{:?}&quot;</span>, <span class="ident">id</span>.<span class="ident">identity</span>());
<span class="doccomment">/// Check if user is authenticated</span>
<span class="comment">// TODO use middleware</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_authenticated</span>(<span class="ident">id</span>: <span class="kw-2">&amp;</span><span class="ident">Identity</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span>()<span class="op">&gt;</span> {
<span class="comment">// access request identity</span>
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="kw">_</span>) <span class="op">=</span> <span class="ident">id</span>.<span class="ident">identity</span>() {
<span class="prelude-val">Ok</span>(<span class="bool-val">true</span>)
<span class="prelude-val">Ok</span>(())
} <span class="kw">else</span> {
<span class="prelude-val">Err</span>(<span class="ident">ServiceError</span>::<span class="ident">AuthorizationRequired</span>)
}
}
<span class="attribute">#[<span class="ident">post</span>(<span class="string">&quot;/api/v1/account/delete&quot;</span>)]</span>
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">delete_account</span>(
<span class="ident">id</span>: <span class="ident">Identity</span>,
<span class="ident">payload</span>: <span class="ident">web</span>::<span class="ident">Json</span><span class="op">&lt;</span><span class="ident">Login</span><span class="op">&gt;</span>,
<span class="ident">data</span>: <span class="ident">web</span>::<span class="ident">Data</span><span class="op">&lt;</span><span class="ident">Data</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="kw">impl</span> <span class="ident">Responder</span><span class="op">&gt;</span> {
<span class="kw">use</span> <span class="ident">argon2_creds</span>::<span class="ident">Config</span>;
<span class="kw">use</span> <span class="ident">sqlx</span>::<span class="ident">Error</span>::<span class="ident">RowNotFound</span>;
<span class="ident">is_authenticated</span>(<span class="kw-2">&amp;</span><span class="ident">id</span>)<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">rec</span> <span class="op">=</span> <span class="ident">sqlx</span>::<span class="macro">query_as</span><span class="macro">!</span>(
<span class="ident">Password</span>,
<span class="string">r#&quot;SELECT password FROM mcaptcha_users WHERE name = ($1)&quot;#</span>,
<span class="kw-2">&amp;</span><span class="ident">payload</span>.<span class="ident">username</span>,
)
.<span class="ident">fetch_one</span>(<span class="kw-2">&amp;</span><span class="ident">data</span>.<span class="ident">db</span>)
.<span class="kw">await</span>;
<span class="kw">match</span> <span class="ident">rec</span> {
<span class="prelude-val">Ok</span>(<span class="ident">s</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">Config</span>::<span class="ident">verify</span>(<span class="kw-2">&amp;</span><span class="ident">s</span>.<span class="ident">password</span>, <span class="kw-2">&amp;</span><span class="ident">payload</span>.<span class="ident">password</span>)<span class="question-mark">?</span> {
<span class="ident">sqlx</span>::<span class="macro">query</span><span class="macro">!</span>(
<span class="string">&quot;DELETE FROM mcaptcha_users WHERE name = ($1)&quot;</span>,
<span class="kw-2">&amp;</span><span class="ident">payload</span>.<span class="ident">username</span>,
)
.<span class="ident">execute</span>(<span class="kw-2">&amp;</span><span class="ident">data</span>.<span class="ident">db</span>)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">HttpResponse</span>::<span class="prelude-val">Ok</span>())
} <span class="kw">else</span> {
<span class="prelude-val">Err</span>(<span class="ident">ServiceError</span>::<span class="ident">WrongPassword</span>)
}
}
<span class="prelude-val">Err</span>(<span class="ident">RowNotFound</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">ServiceError</span>::<span class="ident">UsernameNotFound</span>),
<span class="prelude-val">Err</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">ServiceError</span>::<span class="ident">InternalServerError</span>)<span class="question-mark">?</span>,
}
}
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">test</span>)]</span>
<span class="kw">mod</span> <span class="ident">tests</span> {
<span class="kw">use</span> <span class="ident">actix_web</span>::<span class="ident">http</span>::{<span class="ident">header</span>, <span class="ident">StatusCode</span>};
@@ -363,34 +412,7 @@
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">data</span>::<span class="ident">Data</span>;
<span class="kw">use</span> <span class="kw">crate</span>::<span class="kw-2">*</span>;
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">delete_user</span>(<span class="ident">name</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">data</span>: <span class="kw-2">&amp;</span><span class="ident">Data</span>) {
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">sqlx</span>::<span class="macro">query</span><span class="macro">!</span>(<span class="string">&quot;DELETE FROM mcaptcha_users WHERE name = ($1)&quot;</span>, <span class="ident">name</span>,)
.<span class="ident">execute</span>(<span class="kw-2">&amp;</span><span class="ident">data</span>.<span class="ident">db</span>)
.<span class="kw">await</span>;
}
<span class="macro">macro_rules</span><span class="macro">!</span> <span class="ident">post_request</span> {
(<span class="macro-nonterminal">$</span><span class="macro-nonterminal">serializable</span>:<span class="ident">expr</span>, <span class="macro-nonterminal">$</span><span class="macro-nonterminal">uri</span>:<span class="ident">expr</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="ident">test</span>::<span class="ident">TestRequest</span>::<span class="ident">post</span>()
.<span class="ident">uri</span>(<span class="macro-nonterminal">$</span><span class="macro-nonterminal">uri</span>)
.<span class="ident">header</span>(<span class="ident">header</span>::<span class="ident">CONTENT_TYPE</span>, <span class="string">&quot;application/json&quot;</span>)
.<span class="ident">set_payload</span>(<span class="ident">serde_json</span>::<span class="ident">to_string</span>(<span class="macro-nonterminal">$</span><span class="macro-nonterminal">serializable</span>).<span class="ident">unwrap</span>())
};
}
<span class="macro">macro_rules</span><span class="macro">!</span> <span class="ident">get_server</span> {
() <span class="op">=</span><span class="op">&gt;</span> {
<span class="ident">App</span>::<span class="ident">new</span>()
.<span class="ident">wrap</span>(<span class="ident">middleware</span>::<span class="ident">Logger</span>::<span class="ident">default</span>())
.<span class="ident">wrap</span>(<span class="ident">get_identity_service</span>())
.<span class="ident">wrap</span>(<span class="ident">middleware</span>::<span class="ident">Compress</span>::<span class="ident">default</span>())
.<span class="ident">wrap</span>(<span class="ident">middleware</span>::<span class="ident">NormalizePath</span>::<span class="ident">new</span>(
<span class="ident">middleware</span>::<span class="ident">normalize</span>::<span class="ident">TrailingSlash</span>::<span class="ident">Trim</span>,
))
.<span class="ident">app_data</span>(<span class="ident">get_json_err</span>())
.<span class="ident">configure</span>(<span class="ident">v1_services</span>)
};
}
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">tests</span>::<span class="kw-2">*</span>;
<span class="attribute">#[<span class="ident">actix_rt</span>::<span class="ident">test</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">auth_works</span>() {
@@ -399,39 +421,25 @@
<span class="kw">const</span> <span class="ident">PASSWORD</span>: <span class="kw-2">&amp;</span><span class="ident">str</span> <span class="op">=</span> <span class="string">&quot;longpassword&quot;</span>;
<span class="kw">const</span> <span class="ident">EMAIL</span>: <span class="kw-2">&amp;</span><span class="ident">str</span> <span class="op">=</span> <span class="string">&quot;testuser1@a.com&quot;</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">app</span> <span class="op">=</span> <span class="ident">test</span>::<span class="ident">init_service</span>(<span class="macro">get_server</span><span class="macro">!</span>().<span class="ident">data</span>(<span class="ident">data</span>.<span class="ident">clone</span>())).<span class="kw">await</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">app</span> <span class="op">=</span> <span class="macro">get_app</span><span class="macro">!</span>(<span class="ident">data</span>).<span class="kw">await</span>;
<span class="ident">delete_user</span>(<span class="ident">NAME</span>, <span class="kw-2">&amp;</span><span class="ident">data</span>).<span class="kw">await</span>;
<span class="comment">// 1. Register</span>
<span class="comment">// 1. Register and signin</span>
<span class="kw">let</span> (<span class="ident">data</span>, <span class="kw">_</span>, <span class="ident">signin_resp</span>) <span class="op">=</span> <span class="ident">signin_util</span>(<span class="ident">NAME</span>, <span class="ident">EMAIL</span>, <span class="ident">PASSWORD</span>).<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">cookies</span> <span class="op">=</span> <span class="macro">get_cookie</span><span class="macro">!</span>(<span class="ident">signin_resp</span>);
<span class="comment">// 2. check if duplicate username is allowed</span>
<span class="kw">let</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">Register</span> {
<span class="ident">username</span>: <span class="ident">NAME</span>.<span class="ident">into</span>(),
<span class="ident">password</span>: <span class="ident">PASSWORD</span>.<span class="ident">into</span>(),
<span class="ident">email</span>: <span class="ident">EMAIL</span>.<span class="ident">into</span>(),
};
<span class="kw">let</span> <span class="ident">resp</span> <span class="op">=</span>
<span class="ident">test</span>::<span class="ident">call_service</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">app</span>, <span class="macro">post_request</span><span class="macro">!</span>(<span class="kw-2">&amp;</span><span class="ident">msg</span>, <span class="string">&quot;/api/v1/signup&quot;</span>).<span class="ident">to_request</span>()).<span class="kw">await</span>;
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">resp</span>.<span class="ident">status</span>(), <span class="ident">StatusCode</span>::<span class="ident">OK</span>);
<span class="comment">// 2. check if duplicate username is allowed</span>
<span class="kw">let</span> <span class="ident">duplicate_user_resp</span> <span class="op">=</span>
<span class="ident">test</span>::<span class="ident">call_service</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">app</span>, <span class="macro">post_request</span><span class="macro">!</span>(<span class="kw-2">&amp;</span><span class="ident">msg</span>, <span class="string">&quot;/api/v1/signup&quot;</span>).<span class="ident">to_request</span>()).<span class="kw">await</span>;
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">duplicate_user_resp</span>.<span class="ident">status</span>(), <span class="ident">StatusCode</span>::<span class="ident">BAD_REQUEST</span>);
<span class="comment">// 3. signin</span>
<span class="kw">let</span> <span class="ident">sigin_msg</span> <span class="op">=</span> <span class="ident">Login</span> {
<span class="ident">username</span>: <span class="ident">NAME</span>.<span class="ident">into</span>(),
<span class="ident">password</span>: <span class="ident">PASSWORD</span>.<span class="ident">into</span>(),
};
<span class="kw">let</span> <span class="ident">signin_resp</span> <span class="op">=</span> <span class="ident">test</span>::<span class="ident">call_service</span>(
<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">app</span>,
<span class="macro">post_request</span><span class="macro">!</span>(<span class="kw-2">&amp;</span><span class="ident">sigin_msg</span>, <span class="string">&quot;/api/v1/signin&quot;</span>).<span class="ident">to_request</span>(),
)
.<span class="kw">await</span>;
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">signin_resp</span>.<span class="ident">status</span>(), <span class="ident">StatusCode</span>::<span class="ident">OK</span>);
<span class="kw">let</span> <span class="ident">cookies</span> <span class="op">=</span> <span class="ident">signin_resp</span>.<span class="ident">response</span>().<span class="ident">cookies</span>().<span class="ident">next</span>().<span class="ident">unwrap</span>().<span class="ident">to_owned</span>();
<span class="comment">// 4. sigining in with non-existent user</span>
<span class="comment">// 3. sigining in with non-existent user</span>
<span class="kw">let</span> <span class="ident">nonexistantuser</span> <span class="op">=</span> <span class="ident">Login</span> {
<span class="ident">username</span>: <span class="string">&quot;nonexistantuser&quot;</span>.<span class="ident">into</span>(),
<span class="ident">password</span>: <span class="ident">msg</span>.<span class="ident">password</span>.<span class="ident">clone</span>(),
@@ -445,7 +453,7 @@
<span class="kw">let</span> <span class="ident">txt</span>: <span class="ident">ErrorToResponse</span> <span class="op">=</span> <span class="ident">test</span>::<span class="ident">read_body_json</span>(<span class="ident">userdoesntexist</span>).<span class="kw">await</span>;
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">txt</span>.<span class="ident">error</span>, <span class="macro">format</span><span class="macro">!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">ServiceError</span>::<span class="ident">UsernameNotFound</span>));
<span class="comment">// 5. trying to signin with wrong password</span>
<span class="comment">// 4. trying to signin with wrong password</span>
<span class="kw">let</span> <span class="ident">wrongpassword</span> <span class="op">=</span> <span class="ident">Login</span> {
<span class="ident">username</span>: <span class="ident">NAME</span>.<span class="ident">into</span>(),
<span class="ident">password</span>: <span class="ident">NAME</span>.<span class="ident">into</span>(),
@@ -459,7 +467,7 @@
<span class="kw">let</span> <span class="ident">txt</span>: <span class="ident">ErrorToResponse</span> <span class="op">=</span> <span class="ident">test</span>::<span class="ident">read_body_json</span>(<span class="ident">wrongpassword_resp</span>).<span class="kw">await</span>;
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">txt</span>.<span class="ident">error</span>, <span class="macro">format</span><span class="macro">!</span>(<span class="string">&quot;{}&quot;</span>, <span class="ident">ServiceError</span>::<span class="ident">WrongPassword</span>));
<span class="comment">// 6. signout</span>
<span class="comment">// 5. signout</span>
<span class="kw">let</span> <span class="ident">signout_resp</span> <span class="op">=</span> <span class="ident">test</span>::<span class="ident">call_service</span>(
<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">app</span>,
<span class="macro">post_request</span><span class="macro">!</span>(<span class="kw-2">&amp;</span><span class="ident">wrongpassword</span>, <span class="string">&quot;/api/v1/signout&quot;</span>)
@@ -471,6 +479,28 @@
<span class="ident">delete_user</span>(<span class="ident">NAME</span>, <span class="kw-2">&amp;</span><span class="ident">data</span>).<span class="kw">await</span>;
}
<span class="attribute">#[<span class="ident">actix_rt</span>::<span class="ident">test</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">del_userworks</span>() {
<span class="kw">const</span> <span class="ident">NAME</span>: <span class="kw-2">&amp;</span><span class="ident">str</span> <span class="op">=</span> <span class="string">&quot;testuser2&quot;</span>;
<span class="kw">const</span> <span class="ident">PASSWORD</span>: <span class="kw-2">&amp;</span><span class="ident">str</span> <span class="op">=</span> <span class="string">&quot;longpassword2&quot;</span>;
<span class="kw">const</span> <span class="ident">EMAIL</span>: <span class="kw-2">&amp;</span><span class="ident">str</span> <span class="op">=</span> <span class="string">&quot;testuser1@a.com2&quot;</span>;
<span class="kw">let</span> (<span class="ident">data</span>, <span class="ident">creds</span>, <span class="ident">signin_resp</span>) <span class="op">=</span> <span class="ident">signin_util</span>(<span class="ident">NAME</span>, <span class="ident">EMAIL</span>, <span class="ident">PASSWORD</span>).<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">cookies</span> <span class="op">=</span> <span class="macro">get_cookie</span><span class="macro">!</span>(<span class="ident">signin_resp</span>);
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">app</span> <span class="op">=</span> <span class="macro">get_app</span><span class="macro">!</span>(<span class="ident">data</span>).<span class="kw">await</span>;
<span class="kw">let</span> <span class="ident">delete_user_resp</span> <span class="op">=</span> <span class="ident">test</span>::<span class="ident">call_service</span>(
<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">app</span>,
<span class="macro">post_request</span><span class="macro">!</span>(<span class="kw-2">&amp;</span><span class="ident">creds</span>, <span class="string">&quot;/api/v1/account/delete&quot;</span>)
.<span class="ident">cookie</span>(<span class="ident">cookies</span>)
.<span class="ident">to_request</span>(),
)
.<span class="kw">await</span>;
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">delete_user_resp</span>.<span class="ident">status</span>(), <span class="ident">StatusCode</span>::<span class="ident">OK</span>);
<span class="ident">delete_user</span>(<span class="ident">NAME</span>, <span class="kw-2">&amp;</span><span class="ident">data</span>).<span class="kw">await</span>;
}
}
</pre></div>
</section><section id="search" class="content hidden"></section><section class="footer"></section><script>window.rootPath = "../../../../";window.currentCrate = "guard";</script><script src="../../../../main.js"></script><script src="../../../../source-script.js"></script><script src="../../../../source-files.js"></script><script defer src="../../../../search-index.js"></script></body></html>