Skip to content

Commit e2a6290

Browse files
committed
allow repo-specific configuration of gh_token and gh_hook_token
Define custom getters for retrieving GH secret values. As the getter for each token type defaults to looking for a global value if a repo-specific vaue isn't found, existing deployments don't need to change.
1 parent c0831a9 commit e2a6290

File tree

4 files changed

+29
-4
lines changed

4 files changed

+29
-4
lines changed

lib/action.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,17 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
218218
| _ -> Lwt.return @@ Ok ()
219219

220220
let process_github_notification (ctx : Context.t) headers body =
221+
let validate_signature secrets payload =
222+
let repo = Github.repo_of_notification payload in
223+
let signing_key = Context.gh_hook_token_of_secrets secrets repo.url in
224+
Github.validate_signature ?signing_key ~headers body
225+
in
221226
try%lwt
222227
let secrets = Context.get_secrets_exn ctx in
223228
match Github.parse_exn headers body with
224229
| exception exn -> Exn_lwt.fail ~exn "failed to parse payload"
225230
| payload ->
226-
match Github.validate_signature ?signing_key:secrets.gh_hook_token ~headers body with
231+
match validate_signature secrets payload with
227232
| Error e -> action_error e
228233
| Ok () ->
229234
( match%lwt refresh_repo_config ctx payload with

lib/api_remote.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ module Github : Api.Github = struct
1717
let get_config ~(ctx : Context.t) ~repo =
1818
let secrets = Context.get_secrets_exn ctx in
1919
let url = contents_url ~repo ~path:ctx.config_filename in
20-
let headers = build_headers ?token:secrets.gh_token () in
20+
let token = Context.gh_token_of_secrets secrets repo.url in
21+
let headers = build_headers ?token () in
2122
match%lwt http_request ~headers `GET url with
2223
| Error e -> Lwt.return @@ fmt_error "error while querying remote: %s\nfailed to get config from file %s" e url
2324
| Ok res ->
@@ -41,7 +42,8 @@ module Github : Api.Github = struct
4142
let get_api_commit ~(ctx : Context.t) ~repo ~sha =
4243
let secrets = Context.get_secrets_exn ctx in
4344
let url = commits_url ~repo ~sha in
44-
let headers = build_headers ?token:secrets.gh_token () in
45+
let token = Context.gh_token_of_secrets secrets repo.url in
46+
let headers = build_headers ?token () in
4547
match%lwt http_request ~headers `GET url with
4648
| Ok res -> Lwt.return @@ Ok (Github_j.api_commit_of_string res)
4749
| Error e -> Lwt.return @@ fmt_error "error while querying remote: %s\nfailed to get api commit from file %s" e url

lib/config.atd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
type status_rule <ocaml from="Rule"> = abstract
22
type prefix_rule <ocaml from="Rule"> = abstract
33
type label_rule <ocaml from="Rule"> = abstract
4+
type 'v map_as_object <ocaml from="Common"> = abstract
45

56
(* This type of rule is used for CI build notifications. *)
67
type status_rules = {
@@ -36,10 +37,16 @@ type webhook = {
3637
channel : string; (* name of the Slack channel to post the message *)
3738
}
3839

40+
type gh_repo_secrets = {
41+
?gh_token : string option; (* GitHub personal access token, if repo access requires it *)
42+
?gh_hook_token : string option; (* GitHub webhook token to secure the webhook *)
43+
}
44+
3945
(* This is the structure of the secrets file which stores sensitive information, and
4046
shouldn't be checked into version control. *)
4147
type secrets = {
4248
slack_hooks : webhook list;
4349
?gh_token : string option; (* GitHub personal access token, if repo access requires it *)
4450
?gh_hook_token : string option; (* GitHub webhook token to secure the webhook *)
51+
~repositories <ocaml default="Common.StringMap.empty"> : gh_repo_secrets map_as_object;
4552
}

lib/context.ml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ let get_secrets_exn ctx =
3333
| None -> context_error "secrets is uninitialized"
3434
| Some secrets -> secrets
3535

36+
let gh_token_of_secrets (secrets : Config_t.secrets) repo_url =
37+
match Map.find secrets.repositories repo_url with
38+
| None -> secrets.gh_token
39+
| Some repo_secrets -> repo_secrets.gh_token
40+
41+
let gh_hook_token_of_secrets (secrets : Config_t.secrets) repo_url =
42+
match Map.find secrets.repositories repo_url with
43+
| None -> secrets.gh_hook_token
44+
| Some repo_secrets -> repo_secrets.gh_hook_token
45+
3646
let hook_of_channel ctx channel_name =
3747
let secrets = get_secrets_exn ctx in
3848
match List.find secrets.slack_hooks ~f:(fun webhook -> String.equal webhook.channel channel_name) with
@@ -66,8 +76,9 @@ let refresh_state ctx =
6676
let print_config ctx repo_url =
6777
let cfg = State.find_repo_config_exn ctx.state repo_url in
6878
let secrets = get_secrets_exn ctx in
79+
let token = gh_hook_token_of_secrets secrets repo_url in
6980
log#info "using prefix routing:";
7081
Rule.Prefix.print_prefix_routing cfg.prefix_rules.rules;
7182
log#info "using label routing:";
7283
Rule.Label.print_label_routing cfg.label_rules.rules;
73-
log#info "signature checking %s" (if Option.is_some secrets.gh_hook_token then "enabled" else "disabled")
84+
log#info "signature checking %s" (if Option.is_some token then "enabled" else "disabled")

0 commit comments

Comments
 (0)