diff --git a/.env.sample b/.env.sample index e8f51e43..9b6365ba 100644 --- a/.env.sample +++ b/.env.sample @@ -20,7 +20,7 @@ GITHUB_WEBHOOK_SECRET=MUST_BE_CONFIGURED # ZULIP_API_TOKEN=yyy # Authenticates inbound webhooks from Github -# ZULIP_TOKEN=xxx +# ZULIP_WEBHOOK_SECRET=xxx # Use another endpoint to retrieve teams of the Rust project (useful for local testing) # default: https://team-api.infra.rust-lang.org/v1 diff --git a/README.md b/README.md index c4060dae..811a77e7 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ curl http://localhost:8000/zulip-hook \ -H "Content-Type: application/json" \ -d '{ "data": "", - "token": "", + "token": "", "message": { "sender_id": , "recipient_id": , @@ -121,7 +121,7 @@ curl http://localhost:8000/zulip-hook \ Where: - `CMD` is the exact command you would issue @triagebot on Zulip (ex. open a direct chat with the bot and send "work show") -- `ZULIP_TOKEN`: can be anything. Must correspond to the env var `$ZULIP_TOKEN` on your workstation +- `ZULIP_WEBHOOK_SECRET`: can be anything. Must correspond to the env var `$ZULIP_WEBHOOK_SECRET` on your workstation - `YOUR_ID`: your GitHub user ID. Must be existing in your local triagebot database (table `users` and as foreign key also in `review_prefs`) diff --git a/src/zulip.rs b/src/zulip.rs index 7bf33b11..a80aef8a 100644 --- a/src/zulip.rs +++ b/src/zulip.rs @@ -125,12 +125,29 @@ pub async fn respond(ctx: &Context, req: Request) -> String { serde_json::to_string(&Response { content }).unwrap() } +pub fn get_token_from_env() -> Result { + // ZULIP_WEBHOOK_SECRET is preferred, ZULIP_TOKEN is kept for retrocompatibility but will be deprecated + match std::env::var("ZULIP_WEBHOOK_SECRET") { + Ok(v) => return Ok(v), + Err(_) => (), + } + + match std::env::var("ZULIP_TOKEN") { + Ok(v) => return Ok(v), + Err(_) => (), + } + + log::error!( + "Cannot communicate with Zulip: neither ZULIP_WEBHOOK_SECRET or ZULIP_TOKEN are set." + ); + anyhow::bail!("Cannot communicate with Zulip."); +} + /// Processes a Zulip webhook. /// /// Returns a string of the response, or None if no response is needed. async fn process_zulip_request(ctx: &Context, req: Request) -> anyhow::Result> { - let expected_token = std::env::var("ZULIP_TOKEN").expect("`ZULIP_TOKEN` set for authorization"); - + let expected_token = get_token_from_env()?; if !bool::from(req.token.as_bytes().ct_eq(expected_token.as_bytes())) { anyhow::bail!("Invalid authorization."); }