Skip to content

Commit 5050d89

Browse files
committed
Added common logger
1 parent a25d343 commit 5050d89

File tree

18 files changed

+538
-155
lines changed

18 files changed

+538
-155
lines changed

.github/workflows/security.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Security Audit
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
schedule:
9+
- cron: "0 0 * * 0" # Weekly on Sunday at midnight
10+
11+
jobs:
12+
audit:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Cache Cargo dependencies
18+
uses: actions/cache@v4
19+
with:
20+
path: |
21+
~/.cargo/bin/
22+
~/.cargo/registry/index/
23+
~/.cargo/registry/cache/
24+
~/.cargo/git/db/
25+
target/
26+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
27+
28+
- name: Retrieve Rust version
29+
id: rust-version
30+
run: echo "rust-version=$(grep '^rust ' .tool-versions | awk '{print $2}')" >> $GITHUB_OUTPUT
31+
shell: bash
32+
33+
- name: Set up Rust tool chain
34+
uses: actions-rust-lang/setup-rust-toolchain@v1
35+
with:
36+
toolchain: ${{ steps.rust-version.outputs.rust-version }}
37+
38+
- name: Install cargo-audit
39+
run: cargo install cargo-audit
40+
41+
- name: Run security audit
42+
run: cargo audit
43+
44+
- name: Check for known vulnerabilities in dependencies
45+
uses: actions-rs/audit-check@v1
46+
with:
47+
token: ${{ secrets.GITHUB_TOKEN }}

Cargo.lock

Lines changed: 53 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/common/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ serde = { version = "1.0", features = ["derive"] }
2424
serde_json = "1.0.91"
2525
sha2 = "0.10.6"
2626
tokio = { version = "1.43", features = ["sync", "macros", "io-util", "rt", "time"] }
27+
thiserror = "1.0"
2728
url = "2.4.1"
29+
uuid = { version = "1.0", features = ["v4", "serde"] }

crates/common/src/constants.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ pub const HEADER_X_GEO_INFO_AVAILABLE: HeaderName = HeaderName::from_static("x-g
1515
pub const HEADER_X_GEO_METRO_CODE: HeaderName = HeaderName::from_static("x-geo-metro-code");
1616
pub const HEADER_X_GEO_REGION: HeaderName = HeaderName::from_static("x-geo-region");
1717
pub const HEADER_X_SUBJECT_ID: HeaderName = HeaderName::from_static("x-subject-id");
18+
pub const HEADER_X_REQUEST_ID: HeaderName = HeaderName::from_static("x-request-id");

crates/common/src/cookies.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use cookie::{Cookie, CookieJar};
22
use http::header;
33

44
use crate::http_wrapper::RequestWrapper;
5+
use crate::settings::Settings;
56

67
const COOKIE_MAX_AGE: i32 = 365 * 24 * 60 * 60; // 1 year
78

@@ -32,10 +33,10 @@ pub fn handle_request_cookies<T: RequestWrapper>(req: &T) -> Option<CookieJar> {
3233
}
3334
}
3435

35-
pub fn create_synthetic_cookie(synthetic_id: &str) -> String {
36+
pub fn create_synthetic_cookie(synthetic_id: &str, settings: &Settings) -> String {
3637
format!(
37-
"synthetic_id={}; Domain=.auburndao.com; Path=/; Secure; SameSite=Lax; Max-Age={}",
38-
synthetic_id, COOKIE_MAX_AGE,
38+
"synthetic_id={}; Domain={}; Path=/; Secure; SameSite=Lax; Max-Age={}",
39+
synthetic_id, settings.server.cookie_domain, COOKIE_MAX_AGE,
3940
)
4041
}
4142

@@ -132,10 +133,40 @@ mod tests {
132133

133134
#[test]
134135
fn test_create_synthetic_cookie() {
135-
let result = create_synthetic_cookie("12345");
136+
// Create a test settings
137+
let settings_toml = r#"
138+
[server]
139+
domain = "example.com"
140+
cookie_domain = ".example.com"
141+
142+
[ad_server]
143+
ad_partner_url = "test"
144+
sync_url = "test"
145+
146+
[prebid]
147+
server_url = "test"
148+
149+
[synthetic]
150+
counter_store = "test"
151+
opid_store = "test"
152+
secret_key = "test-key"
153+
template = "test"
154+
"#;
155+
156+
let settings: Settings = config::Config::builder()
157+
.add_source(config::File::from_str(
158+
settings_toml,
159+
config::FileFormat::Toml,
160+
))
161+
.build()
162+
.unwrap()
163+
.try_deserialize()
164+
.unwrap();
165+
166+
let result = create_synthetic_cookie("12345", &settings);
136167
assert_eq!(
137168
result,
138-
"synthetic_id=12345; Domain=.auburndao.com; Path=/; Secure; SameSite=Lax; Max-Age=31536000"
169+
"synthetic_id=12345; Domain=.example.com; Path=/; Secure; SameSite=Lax; Max-Age=31536000"
139170
);
140171
}
141172
}

crates/common/src/error.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use thiserror::Error;
2+
3+
#[derive(Error, Debug)]
4+
pub enum TrustedServerError {
5+
#[error("Configuration error: {0}")]
6+
Config(#[from] config::ConfigError),
7+
8+
#[error("Template rendering error: {0}")]
9+
Template(#[from] handlebars::RenderError),
10+
11+
#[error("Invalid UTF-8: {0}")]
12+
Utf8(#[from] std::str::Utf8Error),
13+
14+
#[error("JSON error: {0}")]
15+
Json(#[from] serde_json::Error),
16+
17+
#[error("HTTP error: {0}")]
18+
Http(String),
19+
20+
#[error("KV store error: {0}")]
21+
KvStore(String),
22+
23+
#[error("Invalid request: {0}")]
24+
InvalidRequest(String),
25+
26+
#[error("Security error: {0}")]
27+
Security(String),
28+
29+
#[error("IO error: {0}")]
30+
Io(#[from] std::io::Error),
31+
}
32+
33+
pub type Result<T> = std::result::Result<T, TrustedServerError>;

crates/common/src/gdpr.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,16 @@ pub fn get_consent_from_request<T: RequestWrapper>(req: &T) -> Option<GdprConsen
6464
None
6565
}
6666

67-
pub fn create_consent_cookie(consent: &GdprConsent) -> String {
67+
pub fn create_consent_cookie(consent: &GdprConsent, settings: &Settings) -> String {
6868
format!(
69-
"gdpr_consent={}; Domain=.auburndao.com; Path=/; Secure; SameSite=Lax; Max-Age=31536000",
70-
serde_json::to_string(consent).unwrap_or_default()
69+
"gdpr_consent={}; Domain={}; Path=/; Secure; SameSite=Lax; Max-Age=31536000",
70+
serde_json::to_string(consent).unwrap_or_default(),
71+
settings.server.cookie_domain
7172
)
7273
}
7374

7475
pub fn handle_consent_request<T: RequestWrapper>(
75-
_settings: &Settings,
76+
settings: &Settings,
7677
mut req: T,
7778
) -> Result<Response, Error> {
7879
match *req.get_method() {
@@ -90,7 +91,10 @@ pub fn handle_consent_request<T: RequestWrapper>(
9091
.with_header(header::CONTENT_TYPE, "application/json")
9192
.with_body(serde_json::to_string(&consent)?);
9293

93-
response.set_header(header::SET_COOKIE, create_consent_cookie(&consent));
94+
response.set_header(
95+
header::SET_COOKIE,
96+
create_consent_cookie(&consent, settings),
97+
);
9498
Ok(response)
9599
}
96100
_ => {

crates/common/src/geo.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use fastly::Response;
2+
3+
use crate::constants::{
4+
HEADER_X_GEO_CITY, HEADER_X_GEO_CONTINENT, HEADER_X_GEO_COORDINATES, HEADER_X_GEO_COUNTRY,
5+
HEADER_X_GEO_INFO_AVAILABLE, HEADER_X_GEO_METRO_CODE,
6+
};
7+
use crate::http_wrapper::RequestWrapper;
8+
9+
/// Copy all geo headers from request to response
10+
pub fn copy_geo_headers<T: RequestWrapper>(req: &T, response: &mut Response) {
11+
let geo_headers = &[
12+
HEADER_X_GEO_CITY,
13+
HEADER_X_GEO_COUNTRY,
14+
HEADER_X_GEO_CONTINENT,
15+
HEADER_X_GEO_COORDINATES,
16+
HEADER_X_GEO_METRO_CODE,
17+
HEADER_X_GEO_INFO_AVAILABLE,
18+
];
19+
20+
for header_name in geo_headers {
21+
if let Some(value) = req.get_header(header_name.clone()) {
22+
response.set_header(header_name, value);
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)