Skip to content

Commit

Permalink
feat(integrations): github auth method
Browse files Browse the repository at this point in the history
  • Loading branch information
fiftin committed Mar 22, 2024
1 parent e5ba366 commit 194a889
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 12 deletions.
38 changes: 31 additions & 7 deletions api/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ import (
"github.com/thedevsaddam/gojsonq/v2"
)

// IsValidPayload checks if the github payload's hash fits with
// isValidHmacPayload checks if the GitHub payload's hash fits with
// the hash computed by GitHub sent as a header
func IsValidPayload(secret, headerHash string, payload []byte) bool {
hash := HashPayload(secret, payload)
func isValidHmacPayload(secret, headerHash string, payload []byte, prefix string) bool {
hash := hmacHashPayload(secret, payload, prefix)
return hmac.Equal(
[]byte(hash),
[]byte(headerHash),
)
}

// HashPayload computes the hash of payload's body according to the webhook's secret token
// hmacHashPayload computes the hash of payload's body according to the webhook's secret token
// see https://developer.github.com/webhooks/securing/#validating-payloads-from-github
// returning the hash as a hexadecimal string
func HashPayload(secret string, payloadBody []byte) string {
func hmacHashPayload(secret string, payloadBody []byte, prefix string) string {
hm := hmac.New(sha1.New, []byte(secret))
hm.Write(payloadBody)
sum := hm.Sum(nil)
return fmt.Sprintf("%x", sum)
return fmt.Sprintf("%s%x", prefix, sum)
}

func ReceiveIntegration(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -77,6 +77,24 @@ func ReceiveIntegration(w http.ResponseWriter, r *http.Request) {
}

switch integration.AuthMethod {
case db.IntegrationAuthGitHub:
var payload []byte
_, err = r.Body.Read(payload)
if err != nil {
log.Error(err)
continue
}

ok := isValidHmacPayload(
integration.AuthSecret.LoginPassword.Password,
r.Header.Get("X-Hub-Signature-256"),
payload,
"sha256=")

if !ok {
log.Error(err)
continue
}
case db.IntegrationAuthHmac:
var payload []byte
_, err = r.Body.Read(payload)
Expand All @@ -85,7 +103,13 @@ func ReceiveIntegration(w http.ResponseWriter, r *http.Request) {
continue
}

if !IsValidPayload(integration.AuthSecret.LoginPassword.Password, r.Header.Get(integration.AuthHeader), payload) {
ok := isValidHmacPayload(
integration.AuthSecret.LoginPassword.Password,
r.Header.Get(integration.AuthHeader),
payload,
"")

if !ok {
log.Error(err)
continue
}
Expand Down
7 changes: 4 additions & 3 deletions db/Integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
type IntegrationAuthMethod string

const (
IntegrationAuthNone = ""
IntegrationAuthToken = "token"
IntegrationAuthHmac = "hmac"
IntegrationAuthNone = ""
IntegrationAuthGitHub = "github"
IntegrationAuthToken = "token"
IntegrationAuthHmac = "hmac"
)

type IntegrationMatchType string
Expand Down
7 changes: 5 additions & 2 deletions web/src/components/IntegrationForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
></v-select>

<v-text-field
v-if="item.auth_method !== ''"
v-if="['token', 'hmac'].includes(item.auth_method)"
v-model="item.auth_header"
label="Auth header"
:disabled="formSaving"
Expand Down Expand Up @@ -71,6 +71,9 @@ export default {
authMethods: [{
id: '',
title: 'None',
}, {
id: 'github',
title: 'GitHub Webhooks',
}, {
id: 'token',
title: 'Token',
Expand Down Expand Up @@ -120,7 +123,7 @@ export default {
async afterLoadData() {
this.keys = (await axios({
keys: 'get',
method: 'get',
url: `/api/project/${this.projectId}/keys`,
responseType: 'json',
})).data;
Expand Down

0 comments on commit 194a889

Please sign in to comment.