mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
Compare commits
2 commits
21da6f9525
...
3b2c1332c2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b2c1332c2 | ||
|
|
be218c89cc |
14 changed files with 107 additions and 86 deletions
2
.github/workflows/rust-docker.yml
vendored
2
.github/workflows/rust-docker.yml
vendored
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
- uses: docker/setup-buildx-action@v1
|
||||
|
||||
# main docker build
|
||||
- run: echo "BRANCH_NAME=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
|
||||
- run: echo "BRANCH_NAME=${GITHUB_REF#refs/heads/}" | sed 's|/|-|g' >> $GITHUB_ENV
|
||||
- uses: docker/build-push-action@v2
|
||||
with:
|
||||
# https://github.com/docker/build-push-action/issues/378
|
||||
|
|
|
|||
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -2616,6 +2616,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"tracing",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ reqwest = { version = "0.12.7" , default-features = false, features = ["rustls-t
|
|||
sentry = { version = "0.36.0", default-features = false, features = ["backtrace", "contexts", "panic", "debug-images", "reqwest", "rustls"] } # replace native-tls with rustls
|
||||
serde = { version = "1.0.196", features = ["derive"] }
|
||||
serde_json = "1.0.117"
|
||||
sqlx = { version = "0.8.2", features = ["runtime-tokio", "postgres", "time", "macros", "uuid"] }
|
||||
sqlx = { version = "0.8.2", features = ["runtime-tokio", "postgres", "time", "chrono", "macros", "uuid"] }
|
||||
tokio = { version = "1.36.0", features = ["full"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] }
|
||||
|
|
|
|||
|
|
@ -34,7 +34,13 @@ pub struct AuthState {
|
|||
}
|
||||
|
||||
impl AuthState {
|
||||
pub fn new(system_id: Option<i32>, app_id: Option<Uuid>, api_key_id: Option<Uuid>, access_level: AccessLevel, internal: bool) -> Self {
|
||||
pub fn new(
|
||||
system_id: Option<i32>,
|
||||
app_id: Option<Uuid>,
|
||||
api_key_id: Option<Uuid>,
|
||||
access_level: AccessLevel,
|
||||
internal: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
system_id,
|
||||
app_id,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{util::json_err, AuthState, ApiContext};
|
||||
use pluralkit_models::{ApiKeyType, PKApiKey, PKSystem, SystemId};
|
||||
use crate::{util::json_err, ApiContext, AuthState};
|
||||
use pk_macros::api_internal_endpoint;
|
||||
use pluralkit_models::{ApiKeyType, PKApiKey, PKSystem, SystemId};
|
||||
|
||||
use axum::{
|
||||
extract::State,
|
||||
|
|
@ -76,7 +76,8 @@ pub async fn create_api_key_user(
|
|||
"valid": true,
|
||||
}))
|
||||
.expect("should not error"),
|
||||
).into_response());
|
||||
)
|
||||
.into_response());
|
||||
}
|
||||
|
||||
let token: PKApiKey = sqlx::query_as(
|
||||
|
|
@ -110,5 +111,6 @@ pub async fn create_api_key_user(
|
|||
"token": token,
|
||||
}))
|
||||
.expect("should not error"),
|
||||
).into_response())
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{util::json_err, ApiContext};
|
||||
use libpk::config;
|
||||
use pluralkit_models::{PrivacyLevel, PKApiKey, PKSystem, PKSystemConfig};
|
||||
use pluralkit_models::{PKApiKey, PKSystem, PKSystemConfig, PrivacyLevel};
|
||||
|
||||
use axum::{
|
||||
extract::{self, State},
|
||||
|
|
@ -201,5 +201,6 @@ pub async fn discord_callback(
|
|||
"token": token,
|
||||
}))
|
||||
.expect("should not error"),
|
||||
).into_response())
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#![feature(let_chains)]
|
||||
|
||||
use auth::{AuthState, INTERNAL_APPID_HEADER, INTERNAL_SYSTEMID_HEADER, INTERNAL_TOKENID_HEADER, INTERNAL_PRIVACYLEVEL_HEADER};
|
||||
use auth::{
|
||||
AuthState, INTERNAL_APPID_HEADER, INTERNAL_PRIVACYLEVEL_HEADER, INTERNAL_SYSTEMID_HEADER,
|
||||
INTERNAL_TOKENID_HEADER,
|
||||
};
|
||||
use axum::{
|
||||
body::Body,
|
||||
extract::{Request as ExtractRequest, State},
|
||||
|
|
@ -13,9 +16,10 @@ use hyper_util::{
|
|||
client::legacy::{connect::HttpConnector, Client},
|
||||
rt::TokioExecutor,
|
||||
};
|
||||
|
||||
use jsonwebtoken::{DecodingKey, EncodingKey};
|
||||
use tracing::{error, info};
|
||||
use pk_macros::api_endpoint;
|
||||
use tracing::{error, info};
|
||||
|
||||
mod auth;
|
||||
mod endpoints;
|
||||
|
|
@ -61,15 +65,24 @@ async fn rproxy(
|
|||
|
||||
if let Some(sid) = auth.system_id() {
|
||||
headers.append(INTERNAL_SYSTEMID_HEADER, sid.into());
|
||||
headers.append(INTERNAL_PRIVACYLEVEL_HEADER, HeaderValue::from_str(&auth.access_level().privacy_level().to_string())?);
|
||||
headers.append(
|
||||
INTERNAL_PRIVACYLEVEL_HEADER,
|
||||
HeaderValue::from_str(&auth.access_level().privacy_level().to_string())?,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(aid) = auth.app_id() {
|
||||
headers.append(INTERNAL_APPID_HEADER, HeaderValue::from_str(&format!("{}", aid))?);
|
||||
headers.append(
|
||||
INTERNAL_APPID_HEADER,
|
||||
HeaderValue::from_str(&format!("{}", aid))?,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(tid) = auth.api_key_id() {
|
||||
headers.append(INTERNAL_TOKENID_HEADER, HeaderValue::from_str(&format!("{}", tid))?);
|
||||
headers.append(
|
||||
INTERNAL_TOKENID_HEADER,
|
||||
HeaderValue::from_str(&format!("{}", tid))?,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(ctx.rproxy_client.request(req).await?.into_response())
|
||||
|
|
@ -136,9 +149,9 @@ fn router(ctx: ApiContext) -> Router {
|
|||
|
||||
.route("/internal/apikey/user", post(endpoints::internal::create_api_key_user))
|
||||
|
||||
.route("/v2/systems/:system_id/oembed.json", get(rproxy))
|
||||
.route("/v2/members/:member_id/oembed.json", get(rproxy))
|
||||
.route("/v2/groups/:group_id/oembed.json", get(rproxy))
|
||||
.route("/v2/systems/{system_id}/oembed.json", get(rproxy))
|
||||
.route("/v2/members/{member_id}/oembed.json", get(rproxy))
|
||||
.route("/v2/groups/{group_id}/oembed.json", get(rproxy))
|
||||
|
||||
.layer(middleware::ratelimit::ratelimiter(ctx.clone(), middleware::ratelimit::do_request_ratelimited))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
use axum::{
|
||||
extract::{Request, State, MatchedPath},
|
||||
extract::{MatchedPath, Request, State},
|
||||
http::StatusCode,
|
||||
middleware::Next,
|
||||
response::Response,
|
||||
};
|
||||
|
||||
use uuid::Uuid;
|
||||
use subtle::ConstantTimeEq;
|
||||
use uuid::Uuid;
|
||||
|
||||
use tracing::error;
|
||||
use sqlx::Postgres;
|
||||
use tracing::error;
|
||||
|
||||
use pluralkit_models::{ApiKeyType, PKApiKey};
|
||||
use crate::auth::{AccessLevel, AuthState};
|
||||
use crate::{util::json_err, ApiContext};
|
||||
use pluralkit_models::{ApiKeyType, PKApiKey};
|
||||
|
||||
pub fn is_part_path<'a, 'b>(part: &'a str, endpoint: &'b str) -> bool {
|
||||
if !endpoint.starts_with("/v2/") {
|
||||
|
|
@ -133,8 +133,10 @@ pub async fn auth(State(ctx): State<ApiContext>, mut req: Request, next: Next) -
|
|||
.flatten()
|
||||
{
|
||||
if system_auth_header.starts_with("Bearer ")
|
||||
&& let Some(tid) =
|
||||
PKApiKey::parse_header_str(system_auth_header[7..].to_string(), &ctx.token_publickey)
|
||||
&& let Some(tid) = PKApiKey::parse_header_str(
|
||||
system_auth_header[7..].to_string(),
|
||||
&ctx.token_publickey,
|
||||
)
|
||||
&& let Some(token) =
|
||||
sqlx::query_as::<Postgres, PKApiKey>("select * from api_keys where id = $1")
|
||||
.bind(&tid)
|
||||
|
|
@ -142,13 +144,10 @@ pub async fn auth(State(ctx): State<ApiContext>, mut req: Request, next: Next) -
|
|||
.await
|
||||
.expect("failed to query apitoken in postgres")
|
||||
{
|
||||
authed_system_id = Some(token.system);
|
||||
authed_api_key_id = Some(tid);
|
||||
access_level = apikey_can_access(&token, req.method().to_string(), endpoint.clone());
|
||||
if access_level != AccessLevel::None {
|
||||
authed_system_id = Some(token.system);
|
||||
}
|
||||
}
|
||||
else if let Some(system_id) =
|
||||
} else if let Some(system_id) =
|
||||
match libpk::db::repository::legacy_token_auth(&ctx.db, system_auth_header).await {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
|
|
@ -201,8 +200,13 @@ pub async fn auth(State(ctx): State<ApiContext>, mut req: Request, next: Next) -
|
|||
false
|
||||
};
|
||||
|
||||
req.extensions_mut()
|
||||
.insert(AuthState::new(authed_system_id, authed_app_id, authed_api_key_id, access_level, internal));
|
||||
req.extensions_mut().insert(AuthState::new(
|
||||
authed_system_id,
|
||||
authed_app_id,
|
||||
authed_api_key_id,
|
||||
access_level,
|
||||
internal,
|
||||
));
|
||||
|
||||
next.run(req).await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ use sqlx::Postgres;
|
|||
use tracing::{debug, error, info, warn};
|
||||
|
||||
use crate::{
|
||||
ApiContext,
|
||||
auth::AuthState,
|
||||
util::{header_or_unknown, json_err},
|
||||
ApiContext,
|
||||
};
|
||||
use pluralkit_models::PKExternalApp;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,13 +60,8 @@ pub struct ApiConfig {
|
|||
|
||||
pub remote_url: String,
|
||||
|
||||
#[serde(default)]
|
||||
pub temp_token2: Option<String>,
|
||||
|
||||
pub token_privatekey: String,
|
||||
pub token_publickey: String,
|
||||
|
||||
pub internal_request_secret: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ jsonwebtoken = { workspace = true }
|
|||
sea-query = "0.32.1"
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true, features = ["preserve_order"] }
|
||||
# in theory we want to default-features = false for sqlx
|
||||
# but cargo doesn't seem to support this
|
||||
sqlx = { workspace = true, features = ["chrono"] }
|
||||
sqlx = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue