Skip to content

Commit 344df97

Browse files
committed
remove oauth flow and focus on self-hosted use case
OAuth can be re-added later on
1 parent ad61933 commit 344df97

File tree

13 files changed

+6
-192
lines changed

13 files changed

+6
-192
lines changed

README.md

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,6 @@ Run the `_build/default/src/monorobot.exe` binary. The following commands are su
3838
3. Click "Install to Workspace", and when prompted to grant permissions to your workspace, click "Allow".
3939
4. Copy the generated OAuth access token (`xoxb-XXXX`) to the `slack_access_token` field of your secrets file. This token is used by the bot to authenticate to the workspace, and remains valid until the token is revoked or the app is uninstalled.
4040

41-
### OAuth Authorization
42-
43-
If you are preparing the app for distribution, you also need to enable automatic OAuth exchange.
44-
45-
You should...
46-
47-
1. In your Slack app dashboard, click on "OAuth & Permissions" in the sidebar. Set the *Redirect URL* to be `<server_domain>/slack/oauth`, and ensure your bot has a *Bot Token Scope* of `chat:write`.
48-
1. You can optionally provide a value for `slack_oauth_state` in your secrets file to [avoid forgery attacks](https://tools.ietf.org/html/rfc6749#section-4.1.1) during the OAuth exchange.
49-
1. Launch the server with the `run` command. Make sure it's reachable externally from same the `server_domain` you used for the GitHub Payload URL. The bot server will listen on `/slack/oauth` for incoming OAuth requests.
50-
1. When the server completes an OAuth exchange and doesn't have an access token defined yet, the secrets file on the server will be regenerated to include a `slack_access_token` field.
51-
52-
Your users should...
53-
54-
1. Go to the following address, replacing the appropriate values (the `state` argument is only needed if you set `slack_oauth_state` in the previous step). `https://slack.com/oauth/v2/authorize?scope=chat:write&client_id=<slack_client_id>&redirect_uri=<server_domain>/slack/oauth&state=<slack_oauth_state>`
55-
1. A page should open asking for permission to install the bot to the workspace. When prompted, click "Allow".
56-
1. Add the bot to all Slack channels the user wants to send notifications to.
57-
5841
### Documentation
5942

6043
The bot expects two configuration files to be present.

documentation/secret_docs.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,16 @@ A secrets file stores sensitive information. Unlike the repository configuration
88

99
```json
1010
{
11-
"slack_client_id": "",
12-
"slack_client_secret": ""
11+
"gh_token": "",
12+
"slack_access_token": ""
1313
}
1414
```
1515

1616
| value | description | optional | default |
1717
|-|-|-|-|
1818
| `gh_token` | specify to grant the bot access to private repositories; omit for public repositories | Yes | - |
1919
| `gh_hook_token` | specify to ensure the bot only receives GitHub notifications from pre-approved repositories | Yes | - |
20-
| `slack_client_id` | slack client ID, used for [oauth](https://api.slack.com/authentication/oauth-v2) authentication; can be found in your slack app's [management page](https://api.slack.com/apps) | No | - |
21-
| `slack_client_secret` | slack client secret, used for [oauth](https://api.slack.com/authentication/oauth-v2) authentication; can be found in your slack app's [management page](https://api.slack.com/apps) | No | - |
22-
| `slack_signing_secret` | specify to verify incoming slack requests; can be found in your slack app's [management page](https://api.slack.com/apps) | Yes | - |
23-
| `slack_oauth_state` | specify some unique value to maintain state b/w oauth request and callback and prevent CSRF (see [RFC6749](https://tools.ietf.org/html/rfc6749#section-4.1.1)) | Yes | - |
24-
| `slack_access_token` | slack bot token obtained via [oauth](https://api.slack.com/authentication/oauth-v2), enabling message posting to the workspace; if not provided initially, the first sucessful oauth exchange will update this field both in memory and on disk | Yes | - |
20+
| `slack_access_token` | slack bot token obtained via [oauth](https://api.slack.com/authentication/oauth-v2), enabling message posting to the workspace | Yes | - |
2521

2622
## `gh_token`
2723

lib/action.ml

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -232,25 +232,4 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
232232
| Context.Context_error msg ->
233233
log#error "%s" msg;
234234
Lwt.return_unit
235-
236-
let process_slack_oauth (ctx : Context.t) args =
237-
try%lwt
238-
let secrets = Context.get_secrets_exn ctx in
239-
match secrets.slack_access_token with
240-
| Some _ -> Lwt.return_unit
241-
| None ->
242-
match Slack.has_valid_state ?oauth_state:secrets.slack_oauth_state ~args with
243-
| false -> action_error "expected state not found in slack authorization request"
244-
| true ->
245-
match List.Assoc.find args "code" ~equal:String.equal with
246-
| None -> action_error "argument `code` not found in slack authorization request"
247-
| Some code ->
248-
( match%lwt Slack_api.update_access_token_of_context ~ctx ~code with
249-
| Error e -> action_error e
250-
| Ok () -> Lwt.return_unit
251-
)
252-
with
253-
| Yojson.Json_error msg -> Lwt.return @@ log#error "failed to parse file as valid JSON (%s)" msg
254-
| Action_error msg -> Lwt.return @@ log#error "%s\naborting slack oauth exchange" msg
255-
| Context.Context_error msg -> Lwt.return @@ log#error "%s" msg
256235
end

lib/api.ml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,4 @@ end
1010

1111
module type Slack = sig
1212
val send_notification : ctx:Context.t -> msg:post_message_req -> (unit, string) Result.t Lwt.t
13-
14-
val update_access_token_of_context : ctx:Context.t -> code:string -> (unit, string) Result.t Lwt.t
1513
end

lib/api_local.ml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ module Slack : Api.Slack = struct
2626
Stdio.printf "will notify #%s\n" msg.channel;
2727
Stdio.printf "%s\n" json;
2828
Lwt.return @@ Ok ()
29-
30-
let update_access_token_of_context ~ctx:_ ~code:_ =
31-
Stdio.printf "will generate token\n";
32-
Lwt.return @@ Ok ()
3329
end
3430

3531
module Slack_simple : Api.Slack = struct
@@ -42,8 +38,6 @@ module Slack_simple : Api.Slack = struct
4238
| Some s -> Printf.sprintf " with %S" s
4339
);
4440
Lwt.return @@ Ok ()
45-
46-
let update_access_token_of_context ~ctx:_ ~code:_ = Lwt.return @@ Error "undefined for local setup"
4741
end
4842

4943
module Slack_json : Api.Slack = struct
@@ -57,6 +51,4 @@ module Slack_json : Api.Slack = struct
5751
log#info "%s" (Uri.to_string url);
5852
log#info "%s" json;
5953
Lwt.return @@ Ok ()
60-
61-
let update_access_token_of_context ~ctx:_ ~code:_ = Lwt.return @@ Error "undefined for local setup"
6254
end

lib/api_remote.ml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -70,31 +70,4 @@ module Slack : Api.Slack = struct
7070
)
7171
| Error e -> Lwt.return @@ fmt_error "error while querying %s: %s\nfailed to send Slack notification" url e
7272
)
73-
74-
let access_token_of_code ~(ctx : Context.t) ~code =
75-
let secrets = Context.get_secrets_exn ctx in
76-
let body = `Form [ "code", code ] in
77-
let auth_header =
78-
Printf.ksprintf Base64.encode_string "%s:%s" secrets.slack_client_id secrets.slack_client_secret
79-
in
80-
let headers = [ Printf.sprintf "Authorization: Basic %s" auth_header ] in
81-
match%lwt Common.http_request ~body ~headers `POST "https://slack.com/api/oauth.v2.access" with
82-
| Error e -> Lwt.return @@ Error e
83-
| Ok data ->
84-
let response = Slack_j.oauth_access_res_of_string data in
85-
( match response.access_token, response.error with
86-
| Some access_token, _ -> Lwt.return @@ Ok access_token
87-
| None, Some e -> Lwt.return @@ Error e
88-
| None, None -> Lwt.return @@ Error "an unknown error occurred while getting access token"
89-
)
90-
91-
let update_access_token_of_context ~ctx ~code =
92-
let secrets = Context.get_secrets_exn ctx in
93-
match%lwt access_token_of_code ~ctx ~code with
94-
| Error e -> Lwt.return @@ Error e
95-
| Ok access_token ->
96-
let secrets = { secrets with slack_access_token = Some access_token } in
97-
ctx.secrets <- Some secrets;
98-
let data = Config_j.string_of_secrets secrets |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string in
99-
Lwt.return @@ write_to_local_file ~data ctx.secrets_filepath
10073
end

lib/config.atd

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,6 @@ type secrets = {
3737
?gh_token : string option;
3838
(* GitHub webhook token to secure the webhook *)
3939
?gh_hook_token : string option;
40-
(* Client ID of the Slack bot; used for OAuth authentication *)
41-
slack_client_id : string;
42-
(* Client secret of the Slack bot; used for OAuth authentication *)
43-
slack_client_secret : string;
44-
(* Slack uses this secret to sign requests; provide to verify incoming Slack requests *)
45-
?slack_signing_secret : string option;
46-
(* if specified, maintains state b/w OAuth request and callback to prevent CSRF
47-
see: https://tools.ietf.org/html/rfc6749#section-4.1.1 *)
48-
?slack_oauth_state : string option;
49-
(* Slack bot token obtained via OAuth, enabling message posting to the workspace;
50-
if not provided initially, the first successful OAuth exchange will update this
51-
field both in memory and on disk *)
40+
(* Slack bot token obtained via OAuth, enabling message posting to the workspace *)
5241
?slack_access_token : string option;
5342
}

lib/slack.atd

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,6 @@ type post_message_req = {
6060
?blocks: message_block list nullable;
6161
}
6262

63-
(* expected payload when exchanging oauth code for access token *)
64-
type oauth_access_res = {
65-
ok: bool;
66-
?access_token: string option;
67-
?error: string option;
68-
}
69-
7063
type post_message_res = {
7164
ok: bool;
7265
?channel: string option;

lib/slack.ml

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -358,25 +358,3 @@ let generate_commit_comment_notification api_commit notification channel =
358358
}
359359
in
360360
{ channel; text = None; attachments = Some [ attachment ]; blocks = None }
361-
362-
let validate_signature ?(version = "v0") ?signing_key ~headers body =
363-
match signing_key with
364-
| None -> Ok ()
365-
| Some key ->
366-
match List.Assoc.find headers "x-slack-signature" ~equal:String.equal with
367-
| None -> Error "unable to find header X-Slack-Signature"
368-
| Some signature ->
369-
match List.Assoc.find headers "x-slack-request-timestamp" ~equal:String.equal with
370-
| None -> Error "unable to find header X-Slack-Request-Timestamp"
371-
| Some timestamp ->
372-
let basestring = Printf.sprintf "%s:%s:%s" version timestamp body in
373-
let expected_signature = Printf.sprintf "%s=%s" version (Common.sign_string_sha256 ~key ~basestring) in
374-
if String.equal expected_signature signature then Ok () else Error "signatures don't match"
375-
376-
let has_valid_state ?oauth_state ~args =
377-
match oauth_state with
378-
| None -> true
379-
| Some expected_state ->
380-
match List.Assoc.find args "state" ~equal:String.equal with
381-
| None -> false
382-
| Some state -> String.equal state expected_state

src/request_handler.ml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ let setup_http ~ctx ~signature ~port ~ip =
3838
log#info "%s" request.body;
3939
let%lwt () = Action.process_github_notification ctx request.headers request.body in
4040
ret (Lwt.return "ok")
41-
| _, [ "slack"; "oauth" ] ->
42-
log#info "slack oauth authorization request received";
43-
let%lwt () = Action.process_slack_oauth ctx request.args in
44-
ret (Lwt.return "ok")
4541
| _, _ ->
4642
log#error "unknown path : %s" (Httpev.show_request request);
4743
ret_err `Not_found "not found"

0 commit comments

Comments
 (0)