diff options
author | Akshay <[email protected]> | 2020-11-11 13:44:32 +0000 |
---|---|---|
committer | Akshay <[email protected]> | 2020-11-11 13:44:32 +0000 |
commit | 4589d5a278c8d1c51e4a465c04945f8a84b6e131 (patch) | |
tree | 3463c9be99e405ea8f48e3a653ce19dfbe174dcc /src | |
parent | f0c96a04f5bfbd85c6c61146c337af0f891a4638 (diff) |
add change password endpoint, compiles on stable rust
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/server.rs | 6 | ||||
-rw-r--r-- | src/handlers/users.rs | 37 | ||||
-rw-r--r-- | src/handlers/users.rs.html | 137 |
3 files changed, 42 insertions, 138 deletions
diff --git a/src/bin/server.rs b/src/bin/server.rs index eb290db..d074e4f 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs | |||
@@ -34,7 +34,11 @@ async fn main() -> std::io::Result<()> { | |||
34 | .route("/existing", web::post().to(users::name_exists)) | 34 | .route("/existing", web::post().to(users::name_exists)) |
35 | .route("/login", web::post().to(users::login)) | 35 | .route("/login", web::post().to(users::login)) |
36 | .route("/{uname}", web::get().to(users::user_details)) | 36 | .route("/{uname}", web::get().to(users::user_details)) |
37 | .route("/new", web::post().to(users::new_user)), | 37 | .route("/new", web::post().to(users::new_user)) |
38 | .route( | ||
39 | "/change_password", | ||
40 | web::post().to(users::change_password), | ||
41 | ), | ||
38 | ) | 42 | ) |
39 | .route("/hey", web::get().to(manual_hello)) | 43 | .route("/hey", web::get().to(manual_hello)) |
40 | }) | 44 | }) |
diff --git a/src/handlers/users.rs b/src/handlers/users.rs index e6b0415..c7bc870 100644 --- a/src/handlers/users.rs +++ b/src/handlers/users.rs | |||
@@ -104,3 +104,40 @@ pub async fn user_details( | |||
104 | } | 104 | } |
105 | } | 105 | } |
106 | } | 106 | } |
107 | |||
108 | #[derive(Deserialize, Debug)] | ||
109 | pub struct ChangePassword { | ||
110 | old_password: String, | ||
111 | new_password: String, | ||
112 | } | ||
113 | |||
114 | pub async fn change_password( | ||
115 | cookie: Identity, | ||
116 | password_details: web::Json<ChangePassword>, | ||
117 | pool: web::Data<TPool>, | ||
118 | ) -> impl Responder { | ||
119 | info!("Change password request: {:?}", password_details); | ||
120 | let conn = pool.get().unwrap(); | ||
121 | if let Some(uname) = cookie.identity() { | ||
122 | let entered_pass = &password_details.old_password; | ||
123 | let new_password = &password_details.new_password; | ||
124 | let selected_user = members | ||
125 | .filter(username.eq(&uname)) | ||
126 | .limit(1) | ||
127 | .first::<Member>(&conn) | ||
128 | .expect("Couldn't connect to DB"); | ||
129 | let hashed_pass = selected_user.password; | ||
130 | if verify(entered_pass, &hashed_pass).unwrap() { | ||
131 | let hashed_new_password = | ||
132 | hash(&new_password, DEFAULT_COST).unwrap(); | ||
133 | diesel::update(members.filter(id.eq(selected_user.id))) | ||
134 | .set(password.eq(hashed_new_password)) | ||
135 | .execute(&conn) | ||
136 | .unwrap(); | ||
137 | return HttpResponse::Ok().body("Changed password successfully"); | ||
138 | } else { | ||
139 | return HttpResponse::Ok().body("Invalid password"); | ||
140 | } | ||
141 | } | ||
142 | return HttpResponse::Unauthorized().body("Login first"); | ||
143 | } | ||
diff --git a/src/handlers/users.rs.html b/src/handlers/users.rs.html deleted file mode 100644 index a233b04..0000000 --- a/src/handlers/users.rs.html +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
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 : --> | ||