Skip to content

Commit 16d3861

Browse files
committed
Fixes password profile saving from mobile applications
- A workaround is added so that mobile applications do not crash when sending a new password profile. - Adds /auth/users/me/ endpoint that returns information about the user.
1 parent a0c462b commit 16d3861

File tree

8 files changed

+93
-3
lines changed

8 files changed

+93
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rockpass"
3-
version = "0.7.1"
3+
version = "0.8.0"
44
authors = ["Óscar García Amor"]
55
license = "GPL-3.0"
66
readme = "README.md"

migrations/2022-03-21-153112_multitokens/down.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CREATE TABLE IF NOT EXISTS tokens_migration (
2-
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
2+
id INTEGER NOT NULL PRIMARY KEY,
33
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
44
token TEXT NOT NULL UNIQUE,
55
created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CREATE TABLE IF NOT EXISTS tokens_migration (
2+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
3+
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
4+
access_token TEXT NOT NULL UNIQUE,
5+
refresh_token TEXT NOT NULL UNIQUE,
6+
created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
7+
modified DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
8+
);
9+
INSERT INTO tokens_migration (
10+
id,
11+
user_id,
12+
access_token,
13+
refresh_token,
14+
created,
15+
modified
16+
) SELECT id, user_id, access_token, refresh_token, created, modified FROM tokens;
17+
DROP TABLE tokens;
18+
ALTER TABLE tokens_migration RENAME TO tokens;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CREATE TABLE IF NOT EXISTS tokens_migration (
2+
id INTEGER NOT NULL PRIMARY KEY,
3+
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
4+
access_token TEXT NOT NULL UNIQUE,
5+
refresh_token TEXT NOT NULL UNIQUE,
6+
created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
7+
modified DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
8+
);
9+
INSERT INTO tokens_migration (
10+
id,
11+
user_id,
12+
access_token,
13+
refresh_token,
14+
created,
15+
modified
16+
) SELECT id, user_id, access_token, refresh_token, created, modified FROM tokens;
17+
DROP TABLE tokens;
18+
ALTER TABLE tokens_migration RENAME TO tokens;

src/main.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ fn rocket() -> _ {
7474
.mount("/", routes![
7575
routes::options_auth_users,
7676
routes::post_auth_users,
77+
routes::options_auth_users_me,
78+
routes::get_auth_users_me,
7779
routes::options_auth_users_set_password,
7880
routes::post_auth_users_set_password,
7981
routes::options_auth_jwt_create,
@@ -167,6 +169,32 @@ mod tests {
167169
assert_eq!(response.into_string().await.unwrap(), r#"{"detail":"User already exists"}"#);
168170
}
169171

172+
#[rocket::async_test]
173+
async fn test_get_auth_users_me() {
174+
let client = Client::tracked(rocket()).await.unwrap();
175+
// Create a user and token
176+
let token = create_token(&client).await;
177+
// Attempt to get user data fails because no access token specified
178+
let request = client.get("/auth/users/me")
179+
.header(ContentType::JSON);
180+
let response = request.dispatch().await;
181+
assert_eq!(response.status(), Status::BadRequest);
182+
// The attempt to get user data fails because, although a valid formatted token is
183+
// specified, the token is not correct.
184+
let request = client.get("/auth/users/me")
185+
.header(ContentType::JSON)
186+
.header(Header::new("authorization", "bearer false"));
187+
let response = request.dispatch().await;
188+
assert_eq!(response.status(), Status::Unauthorized);
189+
// Get user data
190+
let request = client.get("/auth/users/me")
191+
.header(ContentType::JSON)
192+
.header(Header::new("authorization", format!("bearer {}", token.access)));
193+
let response = request.dispatch().await;
194+
assert_eq!(response.status(), Status::Ok);
195+
assert_eq!(response.into_string().await.unwrap(), r#"{"email":"test@rockpass.sample","id":1}"#);
196+
}
197+
170198
#[rocket::async_test]
171199
async fn test_post_auth_jwt_create() {
172200
let client = Client::tracked(rocket()).await.unwrap();
@@ -291,6 +319,13 @@ mod tests {
291319
let response = request.dispatch().await;
292320
assert_eq!(response.status(), Status::Created);
293321
assert_eq!(response.into_string().await.unwrap(), r#"{"detail":"Created new password entry for site rockpass.sample"}"#);
322+
// Password is added with broken scheme
323+
let request = client.post("/passwords")
324+
.header(ContentType::JSON)
325+
.header(Header::new("authorization", format!("bearer {}", token.access)))
326+
.body(r#"{"login":"bob@rockpass.sample","site":"bob.rockpass.sample","uppercase":true,"symbols":true,"lowercase":true,"number":true,"counter":1,"length":16}"#);
327+
let response = request.dispatch().await;
328+
assert_eq!(response.status(), Status::Created);
294329
}
295330

296331
#[rocket::async_test]

src/models.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ pub struct NewPassword {
8282
pub uppercase: bool,
8383
pub symbols: bool,
8484
pub lowercase: bool,
85+
#[serde(alias = "number")]
8586
pub numbers: bool,
8687
pub counter: i32,
88+
#[serde(default = "default_version")]
8789
pub version: i32,
8890
pub length: i32,
8991
}
92+
93+
const fn default_version() -> i32 { 2 }

src/routes.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,21 @@ pub async fn post_auth_users(connection: RockpassDatabase, config: &State<Rockpa
236236
}
237237
}
238238

239+
#[options("/auth/users/me")]
240+
pub async fn options_auth_users_me() -> Status {
241+
Status::NoContent
242+
}
243+
244+
#[get("/auth/users/me")]
245+
pub async fn get_auth_users_me(authorization: Authorization) -> status::Custom<Json<Value>> {
246+
status::Custom(Status::Ok, Json(
247+
json!({
248+
"id": authorization.1.id,
249+
"email": authorization.1.email
250+
})
251+
))
252+
}
253+
239254
#[options("/auth/users/set_password")]
240255
pub async fn options_auth_users_set_password() -> Status {
241256
Status::NoContent

0 commit comments

Comments
 (0)