This repository has been archived by the owner on Oct 19, 2024. It is now read-only.
Add /metrics endpoint for Prometheus #471
This run and associated checks have been archived and are scheduled for deletion.
Learn more about checks retention
Annotations
3 errors and 25 warnings
&-masking with zero:
/home/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitflags-1.3.2/src/lib.rs#L464
error: &-masking with zero
--> src/models/users.rs:14:1
|
14 | / bitflags::bitflags! {
15 | | #[derive(Serialize, Deserialize)]
16 | | #[serde(transparent)]
17 | | pub struct Badges: u64 {
... |
29 | | }
30 | | }
| |_^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
= note: this error originates in the macro `__impl_bitflags` which comes from the expansion of the macro `bitflags::bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
|
&-masking with zero:
/home/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitflags-1.3.2/src/lib.rs#L464
error: &-masking with zero
--> src/models/teams.rs:79:1
|
79 | / bitflags::bitflags! {
80 | | #[derive(Serialize, Deserialize)]
81 | | #[serde(transparent)]
82 | | pub struct OrganizationPermissions: u64 {
... |
94 | | }
95 | | }
| |_^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
= note: this error originates in the macro `__impl_bitflags` which comes from the expansion of the macro `bitflags::bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
|
&-masking with zero:
/home/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitflags-1.3.2/src/lib.rs#L464
error: &-masking with zero
--> src/models/pats.rs:12:1
|
12 | / bitflags::bitflags! {
13 | | #[derive(Serialize, Deserialize)]
14 | | #[serde(transparent)]
15 | | pub struct Scopes: u64 {
... |
107 | | }
108 | | }
| |_^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
= note: `#[deny(clippy::bad_bit_mask)]` on by default
= note: this error originates in the macro `__impl_bitflags` which comes from the expansion of the macro `bitflags::bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
|
security_audit
The following actions uses node12 which is deprecated and will be forced to run on node16: actions-rs/audit-check@v1. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
|
security_audit
3 warnings found!
|
security_audit
Unknown warning kind unsound found, please, file a bug
|
security_audit
Unknown warning kind unsound found, please, file a bug
|
you should consider adding a `Default` implementation for `Scheduler`:
src/scheduler.rs#L9
warning: you should consider adding a `Default` implementation for `Scheduler`
--> src/scheduler.rs:9:5
|
9 | / pub fn new() -> Self {
10 | | Scheduler {
11 | | arbiter: Arbiter::new(),
12 | | }
13 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
help: try adding this
|
8 + impl Default for Scheduler {
9 + fn default() -> Self {
10 + Self::new()
11 + }
12 + }
|
|
you should consider adding a `Default` implementation for `MemoryStore`:
src/ratelimit/memory.rs#L27
warning: you should consider adding a `Default` implementation for `MemoryStore`
--> src/ratelimit/memory.rs:27:5
|
27 | / pub fn new() -> Self {
28 | | debug!("Creating new MemoryStore");
29 | | MemoryStore {
30 | | inner: Arc::new(DashMap::<String, (usize, Duration)>::new()),
31 | | }
32 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
help: try adding this
|
18 + impl Default for MemoryStore {
19 + fn default() -> Self {
20 + Self::new()
21 + }
22 + }
|
|
you should consider adding a `Default` implementation for `AuthQueue`:
src/queue/session.rs#L18
warning: you should consider adding a `Default` implementation for `AuthQueue`
--> src/queue/session.rs:18:5
|
18 | / pub fn new() -> Self {
19 | | AuthQueue {
20 | | session_queue: Mutex::new(HashMap::with_capacity(1000)),
21 | | pat_queue: Mutex::new(HashSet::with_capacity(1000)),
22 | | }
23 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
help: try adding this
|
17 + impl Default for AuthQueue {
18 + fn default() -> Self {
19 + Self::new()
20 + }
21 + }
|
|
you should consider adding a `Default` implementation for `PayoutsQueue`:
src/queue/payouts.rs#L43
warning: you should consider adding a `Default` implementation for `PayoutsQueue`
--> src/queue/payouts.rs:43:5
|
43 | / pub fn new() -> Self {
44 | | PayoutsQueue {
45 | | credential: Default::default(),
46 | | credential_expires: Utc::now() - Duration::days(30),
47 | | }
48 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
help: try adding this
|
42 + impl Default for PayoutsQueue {
43 + fn default() -> Self {
44 + Self::new()
45 + }
46 + }
|
|
you should consider adding a `Default` implementation for `DownloadQueue`:
src/queue/download.rs#L11
warning: you should consider adding a `Default` implementation for `DownloadQueue`
--> src/queue/download.rs:11:5
|
11 | / pub fn new() -> Self {
12 | | DownloadQueue {
13 | | queue: Mutex::new(Vec::with_capacity(1000)),
14 | | }
15 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
help: try adding this
|
10 + impl Default for DownloadQueue {
11 + fn default() -> Self {
12 + Self::new()
13 + }
14 + }
|
|
you should consider adding a `Default` implementation for `AnalyticsQueue`:
src/queue/analytics.rs#L12
warning: you should consider adding a `Default` implementation for `AnalyticsQueue`
--> src/queue/analytics.rs:12:5
|
12 | / pub fn new() -> Self {
13 | | AnalyticsQueue {
14 | | views_queue: DashSet::with_capacity(1000),
15 | | downloads_queue: DashSet::with_capacity(1000),
16 | | playtime_queue: DashSet::with_capacity(1000),
17 | | }
18 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
help: try adding this
|
11 + impl Default for AnalyticsQueue {
12 + fn default() -> Self {
13 + Self::new()
14 + }
15 + }
|
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/threads.rs#L81
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/threads.rs:81:5
|
81 | / pub fn from_str(string: &str) -> ThreadType {
82 | | match string {
83 | | "report" => ThreadType::Report,
84 | | "project" => ThreadType::Project,
... |
87 | | }
88 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/projects.rs#L756
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/projects.rs:756:5
|
756 | / pub fn from_str(string: &str) -> FileType {
757 | | match string {
758 | | "required-resource-pack" => FileType::RequiredResourcePack,
759 | | "optional-resource-pack" => FileType::OptionalResourcePack,
... |
762 | | }
763 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/projects.rs#L721
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/projects.rs:721:5
|
721 | / pub fn from_str(string: &str) -> DependencyType {
722 | | match string {
723 | | "required" => DependencyType::Required,
724 | | "optional" => DependencyType::Optional,
... |
728 | | }
729 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/projects.rs#L573
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/projects.rs:573:5
|
573 | / pub fn from_str(string: &str) -> VersionStatus {
574 | | match string {
575 | | "listed" => VersionStatus::Listed,
576 | | "draft" => VersionStatus::Draft,
... |
580 | | }
581 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/projects.rs#L436
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/projects.rs:436:5
|
436 | / pub fn from_str(string: &str) -> MonetizationStatus {
437 | | match string {
438 | | "force-demonetized" => MonetizationStatus::ForceDemonetized,
439 | | "demonetized" => MonetizationStatus::Demonetized,
... |
442 | | }
443 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/projects.rs#L311
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/projects.rs:311:5
|
311 | / pub fn from_str(string: &str) -> ProjectStatus {
312 | | match string {
313 | | "processing" => ProjectStatus::Processing,
314 | | "rejected" => ProjectStatus::Rejected,
... |
322 | | }
323 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/projects.rs#L250
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/projects.rs:250:5
|
250 | / pub fn from_str(string: &str) -> SideType {
251 | | match string {
252 | | "required" => SideType::Required,
253 | | "optional" => SideType::Optional,
... |
256 | | }
257 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
|
method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`:
src/models/collections.rs#L83
warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
--> src/models/collections.rs:83:5
|
83 | / pub fn from_str(string: &str) -> CollectionStatus {
84 | | match string {
85 | | "listed" => CollectionStatus::Listed,
86 | | "unlisted" => CollectionStatus::Unlisted,
... |
90 | | }
91 | | }
| |_____^
|
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
= note: `#[warn(clippy::should_implement_trait)]` on by default
|
you should consider adding a `Default` implementation for `MockHost`:
src/file_hosting/mock.rs#L10
warning: you should consider adding a `Default` implementation for `MockHost`
--> src/file_hosting/mock.rs:10:5
|
10 | / pub fn new() -> Self {
11 | | MockHost(())
12 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
= note: `#[warn(clippy::new_without_default)]` on by default
help: try adding this
|
9 + impl Default for MockHost {
10 + fn default() -> Self {
11 + Self::new()
12 + }
13 + }
|
|
this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`:
src/database/models/user_item.rs#L355
warning: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`
--> src/database/models/user_item.rs:355:35
|
355 | .delete_many(user_ids.into_iter().flat_map(|(id, username)| {
| ^^^^^^^^^ help: call directly: `iter`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_ref
= note: `#[warn(clippy::into_iter_on_ref)]` on by default
|
called `unwrap` on `projects` after checking its variant with `is_some`:
src/clickhouse/fetch.rs#L237
warning: called `unwrap` on `projects` after checking its variant with `is_some`
--> src/clickhouse/fetch.rs:237:28
|
236 | if projects.is_some() {
| --------------------- help: try: `if let Some(..) = projects`
237 | query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::<Vec<_>>());
| ^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
|
called `unwrap` on `projects` after checking its variant with `is_some`:
src/clickhouse/fetch.rs#L174
warning: called `unwrap` on `projects` after checking its variant with `is_some`
--> src/clickhouse/fetch.rs:174:28
|
173 | if projects.is_some() {
| --------------------- help: try: `if let Some(..) = projects`
174 | query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::<Vec<_>>());
| ^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
|
called `unwrap` on `projects` after checking its variant with `is_some`:
src/clickhouse/fetch.rs#L127
warning: called `unwrap` on `projects` after checking its variant with `is_some`
--> src/clickhouse/fetch.rs:127:28
|
126 | if projects.is_some() {
| --------------------- help: try: `if let Some(..) = projects`
127 | query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::<Vec<_>>());
| ^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
|
called `unwrap` on `projects` after checking its variant with `is_some`:
src/clickhouse/fetch.rs#L80
warning: called `unwrap` on `projects` after checking its variant with `is_some`
--> src/clickhouse/fetch.rs:80:28
|
79 | if projects.is_some() {
| --------------------- help: try: `if let Some(..) = projects`
80 | query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::<Vec<_>>());
| ^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
= note: `#[warn(clippy::unnecessary_unwrap)]` on by default
|
try not to call a closure in the expression where it is declared:
src/auth/flows.rs#L1016
warning: try not to call a closure in the expression where it is declared
--> src/auth/flows.rs:1016:58
|
1016 | let res: Result<HttpResponse, AuthenticationError> = (|| async move {
| __________________________________________________________^
1017 | |
1018 | | let flow = Flow::get(&state, &redis).await?;
1019 | |
... |
1177 | | }
1178 | | })().await;
| |________^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call
= note: `#[warn(clippy::redundant_closure_call)]` on by default
help: try doing something like
|
1016 ~ let res: Result<HttpResponse, AuthenticationError> = async async move {
1017 +
1018 + let flow = Flow::get(&state, &redis).await?;
1019 +
1020 + // Extract cookie header from request
1021 + if let Some(Flow::OAuth {
1022 + user_id,
1023 + provider,
1024 + url,
1025 + }) = flow
1026 + {
1027 + Flow::remove(&state, &redis).await?;
1028 +
1029 + let token = provider.get_token(query).await?;
1030 + let oauth_user = provider.get_user(&token).await?;
1031 +
1032 + let user_id_opt = provider.get_user_id(&oauth_user.id, &**client).await?;
1033 +
1034 + let mut transaction = client.begin().await?;
1035 + if let Some(id) = user_id {
1036 + if user_id_opt.is_some() {
1037 + return Err(AuthenticationError::DuplicateUser);
1038 + }
1039 +
1040 + provider
1041 + .update_user_id(id, Some(&oauth_user.id), &mut transaction)
1042 + .await?;
1043 +
1044 + let user = crate::database::models::User::get_id(id, &**client, &redis).await?;
1045 + if let Some(email) = user.and_then(|x| x.email) {
1046 + send_email(
1047 + email,
1048 + "Authentication method added",
1049 + &format!("When logging into Modrinth, you can now log in using the {} authentication provider.", provider.as_str()),
1050 + "If you did not make this change, please contact us immediately through our support channels on Discord or via email ([email protected]).",
1051 + None,
1052 + )?;
1053 + }
1054 +
1055 + crate::database::models::User::clear_caches(&[(id, None)], &redis).await?;
1056 + transaction.commit().await?;
1057 +
1058 + if let Some(url) = url {
1059 + Ok(HttpResponse::TemporaryRedirect()
1060 + .append_header(("Location", &*url))
1061 + .json(serde_json::json!({ "url": url })))
1062 + } else {
1063 + Err(AuthenticationError::InvalidCredentials)
1064 + }
1065 + } else {
1066 + let user_id = if let Some(user_id) = user_id_opt {
1067 + let user = crate::database::models::User::get_id(user_id, &**client, &redis)
1068 + .await?
1069 + .ok_or_else(|| AuthenticationError::InvalidCredentials)?;
1070 +
1071 + if user.totp_secret.is_some() {
1072 + let flow = Flow::Login2FA { user_id: user.id }
1073 + .insert(Duration::minutes(30), &redis)
1074 + .await?;
1075 +
1076 + if let Some(url) = url {
1077 + let redirect_url = format!(
1078 + "{}{}error=2fa_required&flow={}",
1079 + url,
1080 + if url.contains('?') { "&" } else { "?" },
1081 + flow
1082 + );
1083 +
1084 + return Ok(HttpResponse::TemporaryRedirect()
1085 + .append_header(("Location", &*redirect_url))
1086 + .json(serde_json::json!({ "url": redirect_url })));
1087 + } else {
1088 + let mut ws_conn = {
1089 + let db = sockets.read().await;
1090 +
1091 + let mut x = db
1092 + .auth_sockets
1093 + .get_mut(&state)
1094 + .ok_or_else(|| AuthenticationError::SocketError)?;
1095 +
1096 + x.value_mut().clone()
1097 + };
1098 +
1099 + ws_conn
1100 + .text(
1101 + serde_json::json!({
1102 + "error": "2fa_required",
1103 + "flow": flow,
1104 + }).to_string()
1105 + )
1106 + .await.map_err(|_| AuthenticationError::SocketError)?;
1107 +
1108 + let _ = ws_conn.close(None).await;
1109 +
1110 + return Ok(super::templates::Success {
1111 + icon: user.avatar_url.as_deref().unwrap_or("https://cdn-raw.modrinth.com/placeholder.svg"),
1112 + name: &user.username,
1113 + }.render());
1114 + }
1115 + }
1116 +
1117 + user_id
1118 + } else {
1119 + oauth_user.create_account(provider, &mut transaction, &client, &file_host, &redis).await?
1120 + };
1121 +
1122 + let session = issue_session(req, user_id, &mut transaction, &redis).await?;
1123 + transaction.commit().await?;
1124 +
1125 + if let Some(url) = url {
1126 + let redirect_url = format!(
1127 + "{}{}code={}{}",
1128 + url,
1129 + if url.contains('?') { '&' } else { '?' },
1130 + session.session,
1131 + if user_id_opt.is_none() {
1132 + "&new_account=true"
1133 + } else {
1134 + ""
1135 + }
1136 + );
1137 +
1138 + Ok(HttpResponse::TemporaryRedirect()
1139 + .append_header(("Location", &*redirect_url))
1140 + .json(serde_json::json!({ "url": redirect_url })))
1141 + } else {
1142 + let user = crate::database::models::user_item::User::get_id(
1143 + user_id,
1144 + &**client,
1145 + &redis,
1146 + )
1147 + .await?.ok_or_else(|| AuthenticationError::InvalidCredentials)?;
1148 +
1149 + let mut ws_conn = {
1150 + let db = sockets.read().await;
1151 +
1152 + let mut x = db
1153 + .auth_sockets
1154 + .get_mut(&state)
1155 + .ok_or_else(|| AuthenticationError::SocketError)?;
1156 +
1157 + x.value_mut().clone()
1158 + };
1159 +
1160 + ws_conn
1161 + .text(
1162 + serde_json::json!({
1163 + "code": session.session,
1164 + }).to_string()
1165 + )
1166 + .await.map_err(|_| AuthenticationError::SocketError)?;
1167 + let _ = ws_conn.close(None).await;
1168 +
1169 + return Ok(super::templates::Success {
1170 + icon: user.avatar_url.as_deref().unwrap_or("https://cdn-raw.modrinth.com/placeholder.svg"),
1171 + name: &user.username,
1172 + }.render());
1173 + }
1174 + }
1175 + } else {
1176 + Err::<HttpResponse, AuthenticationError>(AuthenticationError::InvalidCredentials)
1177 + }
1178 ~ }.await;
|
|