handle more fields

This commit is contained in:
Brandon Thomas committed 2022-01-12 01:36:42 -05:00
1 parent 322d957105
commit 0a27c79ee3
4 files changed
+111 -2

No files matched your search

+1
View File
@@ -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