aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2020-11-11 13:44:32 +0000
committerAkshay <[email protected]>2020-11-11 13:44:32 +0000
commit4589d5a278c8d1c51e4a465c04945f8a84b6e131 (patch)
tree3463c9be99e405ea8f48e3a653ce19dfbe174dcc
parentf0c96a04f5bfbd85c6c61146c337af0f891a4638 (diff)
add change password endpoint, compiles on stable rust
-rw-r--r--shell.nix4
-rw-r--r--src/bin/server.rs6
-rw-r--r--src/handlers/users.rs37
-rw-r--r--src/handlers/users.rs.html137
4 files changed, 44 insertions, 140 deletions
diff --git a/shell.nix b/shell.nix
index 5779d87..9f6b23c 100644
--- a/shell.nix
+++ b/shell.nix
@@ -9,8 +9,8 @@ let
9 nixpkgs-mozilla 9 nixpkgs-mozilla
10 (self: super: 10 (self: super:
11 { 11 {
12 rustc = self.latest.rustChannels.nightly.rust; 12 rustc = self.latest.rustChannels.stable.rust;
13 cargo = self.latest.rustChannels.nightly.rust; 13 cargo = self.latest.rustChannels.stable.rust;
14 } 14 }
15 ) 15 )
16 ]; 16 ];
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)]
109pub struct ChangePassword {
110 old_password: String,
111 new_password: String,
112}
113
114pub 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<!--
13pre { font-family: monospace; color: #c0c0c0; background-color: #000000; }
14body { 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">&lt;</span>TPool<span class="Noise">&gt;</span>,
42 item: <span class="rustModPath">web</span><span class="StatusLine">::</span>Json<span class="Noise">&lt;</span>NewMember<span class="Noise">&gt;</span>,
43) <span class="Noise">-&gt;</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">&amp;</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">&amp;</span>conn)
52 .<span class="Function">expect</span>(<span class="Constant">&quot;</span><span class="Constant">Coundn't connect to DB</span><span class="Constant">&quot;</span>);
53 <span class="rustModPath">HttpResponse</span><span class="StatusLine">::</span><span class="Constant">Ok</span>().<span class="Function">body</span>(<span class="Constant">&quot;</span><span class="Constant">Inserted successfully!</span><span class="Constant">&quot;</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">&lt;</span>TPool<span class="Noise">&gt;</span>,
58 item: <span class="Normal">String</span>,
59) <span class="Noise">-&gt;</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">&quot;</span><span class="Constant">target: {:?}</span><span class="Constant">&quot;</span>, item);
62 <span class="Statement">if</span> (members
63 .<span class="Function">filter</span>(username.<span class="Function">eq</span>(<span class="Statement">&amp;</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">&lt;</span>Member<span class="Noise">&gt;</span>(<span class="Statement">&amp;</span>conn)
66 .<span class="Function">expect</span>(<span class="Constant">&quot;</span><span class="Constant">Coundn't connect to DB</span><span class="Constant">&quot;</span>))
67 .<span class="Function">len</span>()
68 <span class="Noise">&gt;</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">&quot;</span><span class="Constant">true</span><span class="Constant">&quot;</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">&quot;</span><span class="Constant">false</span><span class="Constant">&quot;</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">&lt;</span>TPool<span class="Noise">&gt;</span>,
84 cookie: Identity,
85 login_details: <span class="rustModPath">web</span><span class="StatusLine">::</span>Form<span class="Noise">&lt;</span>Login<span class="Noise">&gt;</span>,
86) <span class="Noise">-&gt;</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">&amp;</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">&amp;</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">&lt;</span>Member<span class="Noise">&gt;</span>(<span class="Statement">&amp;</span>conn)
93 .<span class="Function">expect</span>(<span class="Constant">&quot;</span><span class="Constant">Couldn't connect to DB</span><span class="Constant">&quot;</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">&amp;</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">&quot;</span><span class="Constant">Successful login: {} {}</span><span class="Constant">&quot;</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">&quot;</span><span class="Constant">location</span><span class="Constant">&quot;</span>, <span class="Constant">&quot;</span><span class="Constant">/</span><span class="Constant">&quot;</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">-&gt;</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">&quot;</span><span class="Constant">location</span><span class="Constant">&quot;</span>, <span class="Constant">&quot;</span><span class="Constant">/</span><span class="Constant">&quot;</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">&lt;</span><span class="Normal">String</span><span class="Noise">&gt;</span>,
114 pool: <span class="rustModPath">web</span><span class="StatusLine">::</span>Data<span class="Noise">&lt;</span>TPool<span class="Noise">&gt;</span>,
115) <span class="Noise">-&gt;</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">&quot;</span><span class="Constant">Fetching info for: </span><span class="StatusLine">\&quot;</span><span class="Constant">{}</span><span class="StatusLine">\&quot;</span><span class="Constant">&quot;</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">&amp;</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">&lt;</span>Member<span class="Noise">&gt;</span>(<span class="Statement">&amp;</span>conn);
123 <span class="Statement">match</span> selected_user {
124 <span class="Constant">Ok</span>(m) <span class="Noise">=&gt;</span> {
125 <span class="secondAccent">info!</span>(<span class="Constant">&quot;</span><span class="Constant">Found user: {}</span><span class="Constant">&quot;</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">=&gt;</span> {
129 <span class="secondAccent">error!</span>(<span class="Constant">&quot;</span><span class="Constant">User not found: {}</span><span class="Constant">&quot;</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 : -->