1
0
Fork 0
forked from 2sys/shoutdotdev

fix slack bot installation bugs

This commit is contained in:
Brent Schroeter 2025-04-21 21:43:20 -07:00
parent 69e658e949
commit 6da087e17f

View file

@ -105,6 +105,7 @@ async fn start_login(
}; };
const SCOPE_CHANNELS_READ: &str = "channels:read"; const SCOPE_CHANNELS_READ: &str = "channels:read";
const SCOPE_CHAT_WRITE: &str = "chat:write";
const SCOPE_CHAT_WRITE_PUBLIC: &str = "chat:write.public"; const SCOPE_CHAT_WRITE_PUBLIC: &str = "chat:write.public";
let (auth_url, _csrf_token) = app_state let (auth_url, _csrf_token) = app_state
@ -112,6 +113,8 @@ async fn start_login(
.authorize_url(|| csrf_token) .authorize_url(|| csrf_token)
.add_scopes([ .add_scopes([
oauth2::Scope::new(SCOPE_CHANNELS_READ.to_owned()), oauth2::Scope::new(SCOPE_CHANNELS_READ.to_owned()),
// chat:write must be added in order to add chat:write.public
oauth2::Scope::new(SCOPE_CHAT_WRITE.to_owned()),
oauth2::Scope::new(SCOPE_CHAT_WRITE_PUBLIC.to_owned()), oauth2::Scope::new(SCOPE_CHAT_WRITE_PUBLIC.to_owned()),
]) ])
.set_redirect_uri(Cow::Owned( .set_redirect_uri(Cow::Owned(
@ -139,9 +142,9 @@ async fn start_login(
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct AuthRequestQuery { struct AuthRequestQuery {
code: String, code: Option<String>,
/// CSRF token state: Option<String>,
state: String, error: Option<String>,
} }
/// HTTP get handler for /callback /// HTTP get handler for /callback
@ -173,6 +176,23 @@ async fn callback(
.await .await
.unwrap()?; .unwrap()?;
if let Some(message) = query.error {
tracing::warn!("slack oauth error: {}", message);
// This likely indicates that the user has pressed the "Return to
// Shout.dev" button in the Slack OAuth flow.
return Ok(Redirect::to(&format!(
"{}/en/teams/{}/channels/{}",
base_path, team_id, channel_id
)));
}
let oauth_code = query.code.ok_or(AppError::BadRequest(
"OAuth code from Slack is missing.".to_owned(),
))?;
let oauth_state = query.state.ok_or(AppError::BadRequest(
"OAuth state from Slack is missing.".to_owned(),
))?;
let slack_data: SlackBackendConfig = channel let slack_data: SlackBackendConfig = channel
.backend_config .backend_config
.try_into() .try_into()
@ -181,7 +201,7 @@ async fn callback(
let true_csrf_token = slack_data.oauth_state.ok_or(AppError::BadRequest( let true_csrf_token = slack_data.oauth_state.ok_or(AppError::BadRequest(
"No active Slack auth flow.".to_owned(), "No active Slack auth flow.".to_owned(),
))?; ))?;
if true_csrf_token.secret() != &query.state { if true_csrf_token.secret() != &oauth_state {
tracing::debug!("oauth csrf tokens did not match"); tracing::debug!("oauth csrf tokens did not match");
return Err(AppError::Forbidden( return Err(AppError::Forbidden(
"Slack OAuth CSRF tokens do not match.".to_owned(), "Slack OAuth CSRF tokens do not match.".to_owned(),
@ -191,7 +211,7 @@ async fn callback(
tracing::debug!("exchanging authorization code"); tracing::debug!("exchanging authorization code");
let response = app_state let response = app_state
.slack_oauth_client .slack_oauth_client
.exchange_code(AuthorizationCode::new(query.code)) .exchange_code(AuthorizationCode::new(oauth_code))
.set_redirect_uri(Cow::Owned( .set_redirect_uri(Cow::Owned(
RedirectUrl::new(format!( RedirectUrl::new(format!(
"{}{}/en/teams/{}/channels/{}/slack-auth/callback", "{}{}/en/teams/{}/channels/{}/slack-auth/callback",