diff options
Diffstat (limited to 'src/handlers')
-rw-r--r-- | src/handlers/mod.rs | 2 | ||||
-rw-r--r-- | src/handlers/smoke.rs | 15 | ||||
-rw-r--r-- | src/handlers/users.rs | 106 | ||||
-rw-r--r-- | src/handlers/users.rs.html | 137 |
4 files changed, 260 insertions, 0 deletions
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs new file mode 100644 index 0000000..65d3519 --- /dev/null +++ b/src/handlers/mod.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | pub mod smoke; | ||
2 | pub mod users; | ||
diff --git a/src/handlers/smoke.rs b/src/handlers/smoke.rs new file mode 100644 index 0000000..d0a1038 --- /dev/null +++ b/src/handlers/smoke.rs | |||
@@ -0,0 +1,15 @@ | |||
1 | use actix_web::{get, post, HttpResponse, Responder}; | ||
2 | |||
3 | #[get("/")] | ||
4 | async fn hello() -> impl Responder { | ||
5 | HttpResponse::Ok().body("Hello world!") | ||
6 | } | ||
7 | |||
8 | #[post("/echo")] | ||
9 | async fn echo(req_body: String) -> impl Responder { | ||
10 | HttpResponse::Ok().body(req_body) | ||
11 | } | ||
12 | |||
13 | pub async fn manual_hello() -> impl Responder { | ||
14 | HttpResponse::Ok().body("Hey there!") | ||
15 | } | ||
diff --git a/src/handlers/users.rs b/src/handlers/users.rs new file mode 100644 index 0000000..e6b0415 --- /dev/null +++ b/src/handlers/users.rs | |||
@@ -0,0 +1,106 @@ | |||
1 | use crate::models::{Member, NewMember}; | ||
2 | use crate::schema::members::dsl::*; | ||
3 | use crate::TPool; | ||
4 | |||
5 | use actix_identity::Identity; | ||
6 | use actix_web::{web, HttpResponse, Responder}; | ||
7 | use bcrypt::{hash, verify, DEFAULT_COST}; | ||
8 | use diesel::prelude::*; | ||
9 | use log::{error, info}; | ||
10 | use serde::Deserialize; | ||
11 | |||
12 | pub async fn new_user( | ||
13 | pool: web::Data<TPool>, | ||
14 | item: web::Json<NewMember>, | ||
15 | ) -> impl Responder { | ||
16 | let conn = pool.get().unwrap(); | ||
17 | let hashed_item = NewMember { | ||
18 | password: hash(&item.password, DEFAULT_COST).unwrap(), | ||
19 | ..(item.into_inner()) | ||
20 | }; | ||
21 | diesel::insert_into(members) | ||
22 | .values(hashed_item) | ||
23 | .execute(&conn) | ||
24 | .expect("Coundn't connect to DB"); | ||
25 | HttpResponse::Ok().body("Inserted successfully!") | ||
26 | } | ||
27 | |||
28 | pub async fn name_exists( | ||
29 | pool: web::Data<TPool>, | ||
30 | item: String, | ||
31 | ) -> impl Responder { | ||
32 | let conn = pool.get().unwrap(); | ||
33 | info!("target: {:?}", item); | ||
34 | if (members | ||
35 | .filter(username.eq(&item)) | ||
36 | .limit(1) | ||
37 | .load::<Member>(&conn) | ||
38 | .expect("Coundn't connect to DB")) | ||
39 | .len() | ||
40 | > 0 | ||
41 | { | ||
42 | HttpResponse::Ok().body("true") | ||
43 | } else { | ||
44 | HttpResponse::Ok().body("false") | ||
45 | } | ||
46 | } | ||
47 | |||
48 | #[derive(Deserialize)] | ||
49 | pub struct Login { | ||
50 | username: String, | ||
51 | password: String, | ||
52 | } | ||
53 | |||
54 | pub async fn login( | ||
55 | pool: web::Data<TPool>, | ||
56 | cookie: Identity, | ||
57 | login_details: web::Json<Login>, | ||
58 | ) -> impl Responder { | ||
59 | info!("Login hit"); | ||
60 | let conn = pool.get().unwrap(); | ||
61 | let entered_pass = &login_details.password; | ||
62 | let selected_user = members | ||
63 | .filter(username.eq(&login_details.username)) | ||
64 | .limit(1) | ||
65 | .first::<Member>(&conn) | ||
66 | .expect("Couldn't connect to DB"); | ||
67 | let hashed_pass = selected_user.password; | ||
68 | if verify(entered_pass, &hashed_pass).unwrap() { | ||
69 | cookie.remember(login_details.username.clone()); | ||
70 | info!( | ||
71 | "Successful login: {} {}", | ||
72 | selected_user.username, selected_user.email_id | ||
73 | ); | ||
74 | HttpResponse::Ok().finish() | ||
75 | } else { | ||
76 | HttpResponse::Unauthorized().finish() | ||
77 | } | ||
78 | } | ||
79 | |||
80 | pub async fn logout(cookie: Identity) -> impl Responder { | ||
81 | cookie.forget(); | ||
82 | HttpResponse::Found().header("location", "/").finish() | ||
83 | } | ||
84 | |||
85 | pub async fn user_details( | ||
86 | uname: web::Path<String>, | ||
87 | pool: web::Data<TPool>, | ||
88 | ) -> impl Responder { | ||
89 | let conn = pool.get().unwrap(); | ||
90 | let uname = uname.into_inner(); | ||
91 | info!("Fetching info for: \"{}\"", uname); | ||
92 | let selected_user = members | ||
93 | .filter(username.eq(&uname)) | ||
94 | .limit(1) | ||
95 | .first::<Member>(&conn); | ||
96 | match selected_user { | ||
97 | Ok(m) => { | ||
98 | info!("Found user: {}", uname); | ||
99 | HttpResponse::Ok().json(m) | ||
100 | } | ||
101 | Err(_) => { | ||
102 | error!("User not found: {}", uname); | ||
103 | HttpResponse::NotFound().finish() | ||
104 | } | ||
105 | } | ||
106 | } | ||
diff --git a/src/handlers/users.rs.html b/src/handlers/users.rs.html new file mode 100644 index 0000000..a233b04 --- /dev/null +++ b/src/handlers/users.rs.html | |||
@@ -0,0 +1,137 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <meta http-equiv="content-type" content="text/html; charset=UTF-8"> | ||
5 | <title>~/code/rust/actix-tests/src/handlers/users.rs.html</title> | ||
6 | <meta name="Generator" content="Vim/8.0"> | ||
7 | <meta name="plugin-version" content="vim8.1_v1"> | ||
8 | <meta name="syntax" content="rust"> | ||
9 | <meta name="settings" content="use_css,no_foldcolumn,expand_tabs,prevent_copy="> | ||
10 | <meta name="colorscheme" content="plain"> | ||
11 | <style type="text/css"> | ||
12 | <!-- | ||
13 | pre { font-family: monospace; color: #c0c0c0; background-color: #000000; } | ||
14 | body { font-family: monospace; color: #c0c0c0; background-color: #000000; } | ||
15 | * { font-size: 1em; } | ||
16 | .Statement { color: #c0c0c0; background-color: #000000; padding-bottom: 1px; font-weight: bold; } | ||
17 | .Normal { color: #c0c0c0; background-color: #000000; padding-bottom: 1px; } | ||
18 | .Function { color: #c0c0c0; font-weight: bold; } | ||
19 | .secondAccent { color: #c000c0; background-color: #000000; padding-bottom: 1px; } | ||
20 | .Noise { color: #8080ff; background-color: #000000; padding-bottom: 1px; } | ||
21 | .rustModPath { color: #ff40ff; background-color: #000000; padding-bottom: 1px; } | ||
22 | .Constant { color: #008080; background-color: #000000; padding-bottom: 1px; } | ||
23 | .StatusLine { color: #808080; background-color: #000000; padding-bottom: 1px; } | ||
24 | --> | ||
25 | </style> | ||
26 | </head> | ||
27 | <body> | ||
28 | <pre id='vimCodeElement'> | ||
29 | <span class="Noise">use</span> <span class="rustModPath">crate</span><span class="StatusLine">::</span><span class="rustModPath">models</span><span class="StatusLine">::</span>{Member, NewMember}; | ||
30 | <span class="Noise">use</span> <span class="rustModPath">crate</span><span class="StatusLine">::</span><span class="rustModPath">schema</span><span class="StatusLine">::</span><span class="rustModPath">members</span><span class="StatusLine">::</span><span class="rustModPath">dsl</span><span class="StatusLine">::</span><span class="Statement">*</span>; | ||
31 | <span class="Noise">use</span> <span class="rustModPath">crate</span><span class="StatusLine">::</span>TPool; | ||
32 | |||
33 | <span class="Noise">use</span> <span class="rustModPath">actix_identity</span><span class="StatusLine">::</span>Identity; | ||
34 | <span class="Noise">use</span> <span class="rustModPath">actix_web</span><span class="StatusLine">::</span>{web, HttpResponse, Responder}; | ||
35 | <span class="Noise">use</span> <span class="rustModPath">bcrypt</span><span class="StatusLine">::</span>{hash, verify, DEFAULT_COST}; | ||
36 | <span class="Noise">use</span> <span class="rustModPath">diesel</span><span class="StatusLine">::</span><span class="rustModPath">prelude</span><span class="StatusLine">::</span><span class="Statement">*</span>; | ||
37 | <span class="Noise">use</span> <span class="rustModPath">log</span><span class="StatusLine">::</span>{error, info}; | ||
38 | <span class="Noise">use</span> <span class="rustModPath">serde</span><span class="StatusLine">::</span>Deserialize; | ||
39 | |||
40 | <span class="Noise">pub</span> <span class="Noise">async</span> <span class="Noise">fn</span> <span class="Function">new_user</span>( | ||
41 | pool: <span class="rustModPath">web</span><span class="StatusLine">::</span>Data<span class="Noise"><</span>TPool<span class="Noise">></span>, | ||
42 | item: <span class="rustModPath">web</span><span class="StatusLine">::</span>Json<span class="Noise"><</span>NewMember<span class="Noise">></span>, | ||
43 | ) <span class="Noise">-></span> <span class="Noise">impl</span> Responder { | ||
44 | <span class="Noise">let</span> conn <span class="Noise">=</span> pool.<span class="Function">get</span>().<span class="Function">unwrap</span>(); | ||
45 | <span class="Noise">let</span> hashed_item <span class="Noise">=</span> NewMember { | ||
46 | password: <span class="Function">hash</span>(<span class="Statement">&</span>item.password, DEFAULT_COST).<span class="Function">unwrap</span>(), | ||
47 | ..(item.<span class="Function">into_inner</span>()) | ||
48 | }; | ||
49 | <span class="rustModPath">diesel</span><span class="StatusLine">::</span><span class="Function">insert_into</span>(members) | ||
50 | .<span class="Function">values</span>(hashed_item) | ||
51 | .<span class="Function">execute</span>(<span class="Statement">&</span>conn) | ||
52 | .<span class="Function">expect</span>(<span class="Constant">"</span><span class="Constant">Coundn't connect to DB</span><span class="Constant">"</span>); | ||
53 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Constant">Ok</span>().<span class="Function">body</span>(<span class="Constant">"</span><span class="Constant">Inserted successfully!</span><span class="Constant">"</span>) | ||
54 | } | ||
55 | |||
56 | <span class="Noise">pub</span> <span class="Noise">async</span> <span class="Noise">fn</span> <span class="Function">name_exists</span>( | ||
57 | pool: <span class="rustModPath">web</span><span class="StatusLine">::</span>Data<span class="Noise"><</span>TPool<span class="Noise">></span>, | ||
58 | item: <span class="Normal">String</span>, | ||
59 | ) <span class="Noise">-></span> <span class="Noise">impl</span> Responder { | ||
60 | <span class="Noise">let</span> conn <span class="Noise">=</span> pool.<span class="Function">get</span>().<span class="Function">unwrap</span>(); | ||
61 | <span class="secondAccent">info!</span>(<span class="Constant">"</span><span class="Constant">target: {:?}</span><span class="Constant">"</span>, item); | ||
62 | <span class="Statement">if</span> (members | ||
63 | .<span class="Function">filter</span>(username.<span class="Function">eq</span>(<span class="Statement">&</span>item)) | ||
64 | .<span class="Function">limit</span>(<span class="Constant">1</span>) | ||
65 | .<span class="Function">load</span><span class="StatusLine">::</span><span class="Noise"><</span>Member<span class="Noise">></span>(<span class="Statement">&</span>conn) | ||
66 | .<span class="Function">expect</span>(<span class="Constant">"</span><span class="Constant">Coundn't connect to DB</span><span class="Constant">"</span>)) | ||
67 | .<span class="Function">len</span>() | ||
68 | <span class="Noise">></span> <span class="Constant">0</span> | ||
69 | { | ||
70 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Constant">Ok</span>().<span class="Function">body</span>(<span class="Constant">"</span><span class="Constant">true</span><span class="Constant">"</span>) | ||
71 | } <span class="Statement">else</span> { | ||
72 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Constant">Ok</span>().<span class="Function">body</span>(<span class="Constant">"</span><span class="Constant">false</span><span class="Constant">"</span>) | ||
73 | } | ||
74 | } | ||
75 | |||
76 | <span class="secondAccent">#[</span><span class="secondAccent">derive(Deserialize)</span><span class="secondAccent">]</span> | ||
77 | <span class="Noise">pub</span> <span class="Statement">struct</span> <span class="Normal">Login</span> { | ||
78 | username: <span class="Normal">String</span>, | ||
79 | password: <span class="Normal">String</span>, | ||
80 | } | ||
81 | |||
82 | <span class="Noise">pub</span> <span class="Noise">async</span> <span class="Noise">fn</span> <span class="Function">login</span>( | ||
83 | pool: <span class="rustModPath">web</span><span class="StatusLine">::</span>Data<span class="Noise"><</span>TPool<span class="Noise">></span>, | ||
84 | cookie: Identity, | ||
85 | login_details: <span class="rustModPath">web</span><span class="StatusLine">::</span>Form<span class="Noise"><</span>Login<span class="Noise">></span>, | ||
86 | ) <span class="Noise">-></span> <span class="Noise">impl</span> Responder { | ||
87 | <span class="Noise">let</span> conn <span class="Noise">=</span> pool.<span class="Function">get</span>().<span class="Function">unwrap</span>(); | ||
88 | <span class="Noise">let</span> entered_pass <span class="Noise">=</span> <span class="Statement">&</span>login_details.password; | ||
89 | <span class="Noise">let</span> selected_user <span class="Noise">=</span> members | ||
90 | .<span class="Function">filter</span>(username.<span class="Function">eq</span>(<span class="Statement">&</span>login_details.username)) | ||
91 | .<span class="Function">limit</span>(<span class="Constant">1</span>) | ||
92 | .<span class="Function">first</span><span class="StatusLine">::</span><span class="Noise"><</span>Member<span class="Noise">></span>(<span class="Statement">&</span>conn) | ||
93 | .<span class="Function">expect</span>(<span class="Constant">"</span><span class="Constant">Couldn't connect to DB</span><span class="Constant">"</span>); | ||
94 | <span class="Noise">let</span> hashed_pass <span class="Noise">=</span> selected_user.password; | ||
95 | <span class="Statement">if</span> <span class="Function">verify</span>(entered_pass, <span class="Statement">&</span>hashed_pass).<span class="Function">unwrap</span>() { | ||
96 | cookie.<span class="Function">remember</span>(login_details.username.<span class="Function">clone</span>()); | ||
97 | <span class="secondAccent">info!</span>( | ||
98 | <span class="Constant">"</span><span class="Constant">Successful login: {} {}</span><span class="Constant">"</span>, | ||
99 | selected_user.username, selected_user.email_id | ||
100 | ); | ||
101 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Function">Found</span>().<span class="Function">header</span>(<span class="Constant">"</span><span class="Constant">location</span><span class="Constant">"</span>, <span class="Constant">"</span><span class="Constant">/</span><span class="Constant">"</span>).<span class="Function">finish</span>() | ||
102 | } <span class="Statement">else</span> { | ||
103 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Function">Unauthorized</span>().<span class="Function">finish</span>() | ||
104 | } | ||
105 | } | ||
106 | |||
107 | <span class="Noise">pub</span> <span class="Noise">async</span> <span class="Noise">fn</span> <span class="Function">logout</span>(cookie: Identity) <span class="Noise">-></span> <span class="Noise">impl</span> Responder { | ||
108 | cookie.<span class="Function">forget</span>(); | ||
109 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Function">Found</span>().<span class="Function">header</span>(<span class="Constant">"</span><span class="Constant">location</span><span class="Constant">"</span>, <span class="Constant">"</span><span class="Constant">/</span><span class="Constant">"</span>).<span class="Function">finish</span>() | ||
110 | } | ||
111 | |||
112 | <span class="Noise">pub</span> <span class="Noise">async</span> <span class="Noise">fn</span> <span class="Function">user_details</span>( | ||
113 | uname: <span class="rustModPath">web</span><span class="StatusLine">::</span>Path<span class="Noise"><</span><span class="Normal">String</span><span class="Noise">></span>, | ||
114 | pool: <span class="rustModPath">web</span><span class="StatusLine">::</span>Data<span class="Noise"><</span>TPool<span class="Noise">></span>, | ||
115 | ) <span class="Noise">-></span> <span class="Noise">impl</span> Responder { | ||
116 | <span class="Noise">let</span> conn <span class="Noise">=</span> pool.<span class="Function">get</span>().<span class="Function">unwrap</span>(); | ||
117 | <span class="Noise">let</span> uname <span class="Noise">=</span> uname.<span class="Function">into_inner</span>(); | ||
118 | <span class="secondAccent">info!</span>(<span class="Constant">"</span><span class="Constant">Fetching info for: </span><span class="StatusLine">\"</span><span class="Constant">{}</span><span class="StatusLine">\"</span><span class="Constant">"</span>, uname); | ||
119 | <span class="Noise">let</span> selected_user <span class="Noise">=</span> members | ||
120 | .<span class="Function">filter</span>(username.<span class="Function">eq</span>(<span class="Statement">&</span>uname)) | ||
121 | .<span class="Function">limit</span>(<span class="Constant">1</span>) | ||
122 | .<span class="Function">first</span><span class="StatusLine">::</span><span class="Noise"><</span>Member<span class="Noise">></span>(<span class="Statement">&</span>conn); | ||
123 | <span class="Statement">match</span> selected_user { | ||
124 | <span class="Constant">Ok</span>(m) <span class="Noise">=></span> { | ||
125 | <span class="secondAccent">info!</span>(<span class="Constant">"</span><span class="Constant">Found user: {}</span><span class="Constant">"</span>, uname); | ||
126 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Constant">Ok</span>().<span class="Function">json</span>(m) | ||
127 | } | ||
128 | <span class="Constant">Err</span>(_) <span class="Noise">=></span> { | ||
129 | <span class="secondAccent">error!</span>(<span class="Constant">"</span><span class="Constant">User not found: {}</span><span class="Constant">"</span>, uname); | ||
130 | <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Function">NotFound</span>().<span class="Function">finish</span>() | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | </pre> | ||
135 | </body> | ||
136 | </html> | ||
137 | <!-- vim: set foldmethod=manual : --> | ||