diff options
author | pennae <github@quasiparticle.net> | 2022-07-13 10:33:30 +0200 |
---|---|---|
committer | pennae <github@quasiparticle.net> | 2022-07-13 13:27:12 +0200 |
commit | 2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328 (patch) | |
tree | caff55807c5fc773a36aa773cfde9cd6ebbbb6c8 /src/api/auth/invite.rs | |
download | minor-skulk-2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328.tar.gz minor-skulk-2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328.tar.xz minor-skulk-2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328.zip |
initial import
Diffstat (limited to 'src/api/auth/invite.rs')
-rw-r--r-- | src/api/auth/invite.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/api/auth/invite.rs b/src/api/auth/invite.rs new file mode 100644 index 0000000..dd81540 --- /dev/null +++ b/src/api/auth/invite.rs @@ -0,0 +1,47 @@ +use base64::URL_SAFE_NO_PAD; +use chrono::{Duration, Utc}; +use rocket::{http::uri::Reference, serde::json::Json, State}; +use serde::{Deserialize, Serialize}; + +use crate::{api::auth, auth::Authenticated, crypto::SecretBytes, db::DbConn, Config}; + +use super::WithVerifiedFxaLogin; + +pub(crate) async fn generate_invite_link( + db: &DbConn, + cfg: &Config, + ttl: Duration, +) -> anyhow::Result<Reference<'static>> { + let code = base64::encode_config(&SecretBytes::<32>::generate().0, URL_SAFE_NO_PAD); + db.add_invite_code(&code, Utc::now() + ttl).await?; + Ok(Reference::parse_owned(format!("{}/#/register/{}", cfg.location, code)) + .map_err(|e| anyhow!("url building failed at {e}"))?) +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub(crate) struct GenerateReq { + ttl_hours: u32, +} + +#[derive(Debug, Serialize)] +pub(crate) struct GenerateResp { + url: Reference<'static>, +} + +#[post("/generate", data = "<req>")] +pub(crate) async fn generate( + db: &DbConn, + cfg: &State<Config>, + req: Authenticated<GenerateReq, WithVerifiedFxaLogin>, +) -> auth::Result<GenerateResp> { + if !req.context.verified { + return Err(auth::Error::UnverifiedSession); + } + let user = db.get_user_by_id(&req.context.uid).await?; + if user.email != cfg.invite_admin_address { + return Err(auth::Error::InvalidAuthToken); + } + let url = generate_invite_link(&db, &cfg, Duration::hours(req.body.ttl_hours as i64)).await?; + Ok(Json(GenerateResp { url })) +} |