Validate Slack OAuth2 token response
Check the ok and error fields from Slack's token response and reject flows with a missing access token. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
@@ -44,6 +44,8 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
SlackTokenResponse struct {
|
SlackTokenResponse struct {
|
||||||
|
Ok bool `json:"ok"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
IncomingWebhook *IncomingWebhook `json:"incoming_webhook,omitempty"`
|
IncomingWebhook *IncomingWebhook `json:"incoming_webhook,omitempty"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -115,6 +117,16 @@ func ParseSlackTokenResponse(body []byte, oauth2Conn OAuth2Connection, organizat
|
|||||||
return nil, nil, fmt.Errorf("cannot decode Slack token response: %w", err)
|
return nil, nil, fmt.Errorf("cannot decode Slack token response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if slackResponse.Error != "" {
|
||||||
|
return nil, nil, fmt.Errorf("cannot complete Slack OAuth2 flow: %s", slackResponse.Error)
|
||||||
|
}
|
||||||
|
if !slackResponse.Ok {
|
||||||
|
return nil, nil, fmt.Errorf("cannot complete Slack OAuth2 flow: ok=false")
|
||||||
|
}
|
||||||
|
if oauth2Conn.AccessToken == "" {
|
||||||
|
return nil, nil, fmt.Errorf("cannot complete Slack OAuth2 flow: missing access token")
|
||||||
|
}
|
||||||
|
|
||||||
settings := SlackSettings{}
|
settings := SlackSettings{}
|
||||||
if slackResponse.IncomingWebhook != nil {
|
if slackResponse.IncomingWebhook != nil {
|
||||||
settings.WebhookURL = slackResponse.IncomingWebhook.URL
|
settings.WebhookURL = slackResponse.IncomingWebhook.URL
|
||||||
|
|||||||
@@ -64,4 +64,28 @@ func TestParseSlackTokenResponse(t *testing.T) {
|
|||||||
assert.Empty(t, conn.Settings.ChannelID)
|
assert.Empty(t, conn.Settings.ChannelID)
|
||||||
assert.Equal(t, "xoxb-test", conn.AccessToken)
|
assert.Equal(t, "xoxb-test", conn.AccessToken)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("slack error response", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
body := []byte(`{"ok":false,"error":"invalid_code"}`)
|
||||||
|
|
||||||
|
conn, returnedOrgID, err := ParseSlackTokenResponse(body, base, orgID)
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Nil(t, conn)
|
||||||
|
assert.Nil(t, returnedOrgID)
|
||||||
|
assert.ErrorContains(t, err, "invalid_code")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("missing access token", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
body := []byte(`{"ok":true}`)
|
||||||
|
connWithoutToken := base
|
||||||
|
connWithoutToken.AccessToken = ""
|
||||||
|
|
||||||
|
conn, returnedOrgID, err := ParseSlackTokenResponse(body, connWithoutToken, orgID)
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Nil(t, conn)
|
||||||
|
assert.Nil(t, returnedOrgID)
|
||||||
|
assert.ErrorContains(t, err, "missing access token")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user