Skip to content

Simplify authenticate_user() function #3328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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