use actix_web::{App, HttpMessage, HttpResponse, HttpServer, get};
use cookiebox::cookiebox_macros::{FromRequest, cookie};
use cookiebox::cookies::{Cookie, CookieName, IncomingConfig, OutgoingConfig};
use cookiebox::{Attributes, SameSite};
use cookiebox::{
CookieMiddleware, Key, Processor, ProcessorConfig,
config::{CryptoAlgorithm, CryptoRule},
};
use serde::{Deserialize, Serialize};
use serde_json::json;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let mut cookie_config = ProcessorConfig::default();
let crypto_rule = CryptoRule {
cookie_names: vec!["__cookie-b".to_string()],
algorithm: CryptoAlgorithm::Encryption,
key: Key::generate(),
fallbacks: vec![],
};
cookie_config.crypto_rules.push(crypto_rule);
let processor: Processor = cookie_config.into();
HttpServer::new(move || {
App::new()
.wrap(CookieMiddleware::new(processor.clone()))
.service(get_cookie_a)
.service(add_cookie_a)
.service(update_cookie_a)
.service(remove_cookie_a)
.service(get_cookie_b)
.service(add_cookie_b)
.service(update_cookie_b)
.service(remove_cookie_b)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CookieData {
pub data: String,
}
#[cookie(name = "__cookie-a")]
pub struct CookieA;
#[cookie(name = "__cookie-b")]
pub struct CookieB;
impl IncomingConfig for CookieA {
type Get = String;
}
impl OutgoingConfig for CookieA {
type Insert = String;
}
impl IncomingConfig for CookieB {
type Get = CookieData;
}
impl OutgoingConfig for CookieB {
type Insert = (String, i32);
fn serialize(values: Self::Insert) -> serde_json::Value {
json!({
"data": format!("Name: {} - Age: {}", values.0, values.1)
})
}
fn attributes<'c>() -> Attributes<'c> {
Attributes::new().same_site(SameSite::Lax).http_only(true)
}
}
#[derive(FromRequest)]
pub struct CookieCollection<'c> {
cookie_a: Cookie<'c, CookieA>,
cookie_b: Cookie<'c, CookieB>,
}
#[get("add_cookie_b")]
async fn add_cookie_b(cookies_collection: CookieCollection<'_>) -> HttpResponse {
cookies_collection
.cookie_b
.insert(("Scarlet".to_string(), 27));
HttpResponse::Ok().body("Encrypted cookie added")
}
#[get("get_cookie_b")]
async fn get_cookie_b(cookies_collection: CookieCollection<'_>) -> HttpResponse {
let data = cookies_collection
.cookie_b
.get()
.map_err(|e| eprint!("Unable to get cookie data - {e}"));
HttpResponse::Ok().json(data)
}
#[get("update_cookie_b")]
async fn update_cookie_b(cookies_collection: CookieCollection<'_>) -> HttpResponse {
let old_data = cookies_collection
.cookie_b
.get()
.map_err(|e| eprint!("Unable to get cookie data - {e}"));
cookies_collection
.cookie_b
.insert(("Jason".to_string(), 22));
HttpResponse::Ok().body(format!(
"old data: {:?} - Go to get_cookie_b to check the new value",
old_data
))
}
#[get("remove_cookie_b")]
async fn remove_cookie_b(cookies_collection: CookieCollection<'_>) -> HttpResponse {
cookies_collection.cookie_b.remove();
HttpResponse::Ok().body("__cookie-b removed")
}
#[get("add_cookie_a")]
async fn add_cookie_a(cookies_collection: CookieCollection<'_>) -> HttpResponse {
cookies_collection.cookie_a.insert("Cookie A".to_string());
HttpResponse::Ok().body("__cookie-a added")
}
#[get("get_cookie_a")]
async fn get_cookie_a(cookies_collection: CookieCollection<'_>) -> HttpResponse {
let data = cookies_collection
.cookie_a
.get()
.map_err(|e| eprint!("Unable to get cookie data - {e}"));
HttpResponse::Ok().body(format!("{:?}", data))
}
#[get("update_cookie_a")]
async fn update_cookie_a(cookies_collection: CookieCollection<'_>) -> HttpResponse {
let old_data = cookies_collection
.cookie_a
.get()
.map_err(|e| eprint!("Unable to get cookie data - {e}"));
cookies_collection
.cookie_a
.insert("New cookie A value".to_string());
HttpResponse::Ok().body(format!(
"old data: {:?} - Go to get_cookie_a to check the new value",
old_data
))
}
#[get("remove_cookie_a")]
async fn remove_cookie_a(cookies_collection: CookieCollection<'_>) -> HttpResponse {
cookies_collection.cookie_a.remove();
HttpResponse::Ok().body("__cookie-a removed")
}