Skip to content

Commit

Permalink
Auto merge of #3328 - Turbo87:authenticate-user, r=JohnTitor
Browse files Browse the repository at this point in the history
Simplify `authenticate_user()` function

The function was a bit hard to read and difficult to extend (see #3307). This PR simplifies it a little bit by returning early if a suitable authentication method was found.

r? `@jtgeibel`
  • Loading branch information
bors committed Mar 3, 2021
2 parents 5d9766a + 9680a62 commit 5e17d5e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 31 deletions.
64 changes: 34 additions & 30 deletions src/controllers/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,38 +62,42 @@ fn authenticate_user(req: &dyn RequestExt) -> AppResult<AuthenticatedUser> {
let session = req.session();
let user_id_from_session = session.get("user_id").and_then(|s| s.parse::<i32>().ok());

let (user_id, token_id) = if let Some(id) = user_id_from_session {
(id, None)
} else {
// Otherwise, look for an `Authorization` header on the request
let maybe_authorization: Option<String> = {
req.headers()
.get(header::AUTHORIZATION)
.and_then(|h| h.to_str().ok())
.map(|h| h.to_string())
};
if let Some(header_value) = maybe_authorization {
let (user_id, token_id) = ApiToken::find_by_api_token(&conn, &header_value)
.map(|token| (token.user_id, Some(token.id)))
.map_err(|e| {
if e.is::<InsecurelyGeneratedTokenRevoked>() {
e
} else {
e.chain(internal("invalid token")).chain(forbidden())
}
})?;

(user_id, token_id)
} else {
// Unable to authenticate the user
return Err(internal("no cookie session or auth header found")).chain_error(forbidden);
}
};
if let Some(id) = user_id_from_session {
let user = User::find(&conn, id)
.chain_error(|| internal("user_id from cookie not found in database"))?;

return Ok(AuthenticatedUser {
user,
token_id: None,
});
}

// Otherwise, look for an `Authorization` header on the request
let maybe_authorization = req
.headers()
.get(header::AUTHORIZATION)
.and_then(|h| h.to_str().ok());

if let Some(header_value) = maybe_authorization {
let token = ApiToken::find_by_api_token(&conn, header_value).map_err(|e| {
if e.is::<InsecurelyGeneratedTokenRevoked>() {
e
} else {
e.chain(internal("invalid token")).chain(forbidden())
}
})?;

let user = User::find(&conn, user_id)
.chain_error(|| internal("user_id from cookie or token not found in database"))?;
let user = User::find(&conn, token.user_id)
.chain_error(|| internal("user_id from token not found in database"))?;

return Ok(AuthenticatedUser {
user,
token_id: Some(token.id),
});
}

Ok(AuthenticatedUser { user, token_id })
// Unable to authenticate the user
return Err(internal("no cookie session or auth header found")).chain_error(forbidden);
}

impl<'a> UserAuthenticationExt for dyn RequestExt + 'a {
Expand Down
2 changes: 1 addition & 1 deletion src/tests/authentication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ static URL: &str = "/api/v1/me/updates";
static MUST_LOGIN: &[u8] =
b"{\"errors\":[{\"detail\":\"must be logged in to perform that action\"}]}";
static INTERNAL_ERROR_NO_USER: &str =
"user_id from cookie or token not found in database caused by NotFound";
"user_id from cookie not found in database caused by NotFound";

fn call(app: &TestApp, mut request: MockRequest) -> HandlerResult {
app.as_middleware().call(&mut request)
Expand Down

0 comments on commit 5e17d5e

Please sign in to comment.