mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-02 00:18:17 +00:00
handle more fields
This commit is contained in:
1 parent
322d957105
commit
0a27c79ee3
4 files changed
+111
-2
No files matched your search
@@ -12,4 +12,5 @@
|
||||
|
||||
pub mod cors;
|
||||
pub mod endpoints;
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
@@ -0,0 +1,100 @@
|
||||
use actix_web::HttpRequest;
|
||||
use actix_web::dev::ServiceRequest;
|
||||
use log::{info};
|
||||
use actix_web::http::{HeaderMap, HeaderName};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn get_request_ip(request: &HttpRequest) -> String {
|
||||
let headers = request.headers();
|
||||
let maybe_x_forwarded = get_ip_from_header(headers, "x-forwarded-for");
|
||||
let maybe_forwarded = get_ip_from_header(headers, "forwarded");
|
||||
|
||||
info!("(1) x-forwarded-for: {:?}, forwarded: {:?}", maybe_x_forwarded, maybe_forwarded);
|
||||
|
||||
let maybe_ip = maybe_x_forwarded.or(maybe_forwarded);
|
||||
|
||||
match maybe_ip {
|
||||
Some(ip_address) => ip_address,
|
||||
None => {
|
||||
// If we're running without the upstream Rust proxy, we can grab 'x-forarded-for', which is
|
||||
// populated by the DigitalOcean load balancer.
|
||||
let ip_address_and_port = request.connection_info()
|
||||
.remote_addr()
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let ip_address = ip_address_and_port.split(":")
|
||||
.collect::<Vec<&str>>()
|
||||
.get(0)
|
||||
.copied()
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
info!("Forwarded IP address (1): {}", &ip_address);
|
||||
ip_address
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: De-duplicate
|
||||
pub fn get_service_request_ip(request: &ServiceRequest) -> String {
|
||||
let headers = request.headers();
|
||||
let maybe_x_forwarded = get_ip_from_header(headers, "x-forwarded-for");
|
||||
let maybe_forwarded = get_ip_from_header(headers, "forwarded");
|
||||
|
||||
info!("(2) x-forwarded-for: {:?}, forwarded: {:?}", maybe_x_forwarded, maybe_forwarded);
|
||||
|
||||
let maybe_ip = maybe_x_forwarded.or(maybe_forwarded);
|
||||
|
||||
match maybe_ip {
|
||||
Some(ip_address) => ip_address,
|
||||
None => {
|
||||
// If we're running without the upstream Rust proxy, we can grab 'x-forarded-for', which is
|
||||
// populated by the DigitalOcean load balancer.
|
||||
let ip_address_and_port = request.connection_info()
|
||||
.remote_addr()
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let ip_address = ip_address_and_port.split(":")
|
||||
.collect::<Vec<&str>>()
|
||||
.get(0)
|
||||
.copied()
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
info!("(2) Forwarded IP address: {}", &ip_address);
|
||||
ip_address
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_ip_from_header(headers: &HeaderMap, header_name: &str) -> Option<String> {
|
||||
if let Ok(header_name) = HeaderName::from_str(header_name) {
|
||||
headers.get(&header_name)
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.and_then(|value| first_ip_from_list(value))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// NB: GKE packs in multiple IP addresses into the header:
|
||||
// Example of header: x-forwarded-for: Some("136.55.189.34, 34.117.9.171")
|
||||
fn first_ip_from_list(ip_list: &str) -> Option<String> {
|
||||
ip_list.split(",")
|
||||
.into_iter()
|
||||
.map(|ip| ip.trim())
|
||||
.find(|ip| !ip.is_empty())
|
||||
.map(|ip| ip.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::http_server::web_utils::ip_address::first_ip_from_list;
|
||||
|
||||
#[test]
|
||||
fn test_first_ip() {
|
||||
assert_eq!(first_ip_from_list("1.2.3.4"), Some("1.2.3.4".to_string()));
|
||||
assert_eq!(first_ip_from_list("1.2.3.4, 34.117.9.171"), Some("1.2.3.4".to_string()));
|
||||
assert_eq!(first_ip_from_list(", 1.2.3.4"), Some("1.2.3.4".to_string()));
|
||||
assert_eq!(first_ip_from_list("1.2.3.4, "), Some("1.2.3.4".to_string()));
|
||||
assert_eq!(first_ip_from_list(""), None);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod get_request_ip;
|
||||
@@ -11,6 +11,7 @@ use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use twitch_oauth2::tokens::BearerTokenType::UserToken;
|
||||
use twitch_oauth2::{CsrfToken, TwitchToken};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct QueryParams {
|
||||
@@ -139,13 +140,19 @@ pub async fn oauth_end_enroll_from_redirect(
|
||||
info!("Never expiring: {:?}", never_expiring);
|
||||
info!("Expires in (don't store): {:?}", expires_in); // Should be ~4 hours
|
||||
|
||||
let ip_address = get_request_ip(&http_request);
|
||||
|
||||
let expires_seconds = expires_in.as_secs() as u32; // NB: Silent overflow
|
||||
|
||||
let mut insert_builder =
|
||||
TwitchOauthTokenInsertBuilder::new(&user_id, &auth_token)
|
||||
.set_expires_in_seconds(Some(expires_seconds))
|
||||
.set_twitch_username(Some(&twitch_username));
|
||||
//.set_has_bits_read(true)
|
||||
.set_twitch_username(Some(&twitch_username))
|
||||
.set_refresh_token(refresh_token.as_deref())
|
||||
.set_ip_address_creation(Some(&ip_address));
|
||||
//.set_user_token()
|
||||
//.set_token_type()
|
||||
//.set_has_bits_read(true) ...
|
||||
|
||||
let result = insert_builder.insert(&server_state.backends.mysql_pool)
|
||||
.await
|
||||
|
||||
Reference in new issue
Block a user