Skip to content

Commit 67cfe61

Browse files
committed
Refactor auth code
Up until this point our "auth" code was scattered all over the place and mixed up authentication (who are you?) and authorization (what are you allowed to do?) in multiple places: - Whether a user account was locked was checked as part of authentication, although it is more of an authorization concern. - Whether a user has a verified email address was checked in the individual endpoints, if at all. - Whether a user is an admin was also checked in the individual endpoints that were adjusted to support admin users. - Whether a user is an owner (or team member) of a crate was also checked in the individual endpoints, in various different ways. - Whether an API token has the right scopes was also checked as part of authentication, but it is an authorization concern. This commit centralizes these checks with a three step approach: 1. In the first step the endpoint uses one of the `Credentials` structs as an axum request extractor to extract the raw credentials from the request metadata (user ID from session cookie, API token, Trusted Publishing token). 2. The credentials are used to look up a corresponding user (or Trusted Publishing token) from the database. 3. The authenticated entity is used to check for authorization of the requested operation. The second and third step are folded into one fn call (`.validate(permission)`) to make it harder to use an authenticated entity without knowing if they are authorized for the operation. While the auth code and the endpoints have changed quite a bit due to this refactoring, the test code is mostly the same except for a few minor details caused by using the request extractors now.
1 parent de3ac56 commit 67cfe61

File tree

36 files changed

+1216
-759
lines changed

36 files changed

+1216
-759
lines changed

crates/crates_io_trustpub/src/access_token.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,15 @@ impl FromStr for AccessToken {
8080
}
8181

8282
/// The error type for parsing access tokens.
83-
#[derive(Debug, Clone, PartialEq, Eq)]
83+
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
8484
pub enum AccessTokenError {
85+
#[error("Missing prefix `{}`", AccessToken::PREFIX)]
8586
MissingPrefix,
87+
#[error("Invalid token length")]
8688
InvalidLength,
89+
#[error("Invalid character in token")]
8790
InvalidCharacter,
91+
#[error("Invalid checksum: claimed `{claimed}`, actual `{actual}`")]
8892
InvalidChecksum { claimed: char, actual: char },
8993
}
9094

0 commit comments

Comments
 (0)