Skip to content

Commit

Permalink
Add an option to let go remote signer respond directly through webhooks.
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenlu committed Mar 22, 2024
1 parent ee986c6 commit 1074ca1
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 27 deletions.
5 changes: 5 additions & 0 deletions examples/remote-signing-server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ const API_CLIENT_ID = "API_CLIENT_ID"
const API_CLIENT_SECRET = "API_CLIENT_SECRET"
const WEBHOOK_SECRET = "WEBHOOK_SECRET"
const MASTER_SEED_HEX = "MASTER_SEED_HEX"
const RESPOND_DIRECTLY = "RESPOND_DIRECTLY"

type Config struct {
ApiEndpoint *string
ApiClientId string
ApiClientSecret string
WebhookSecret string
MasterSeed []byte
RespondDirectly bool
}

func NewConfigFromEnv() (*Config, error) {
Expand Down Expand Up @@ -54,6 +56,8 @@ func NewConfigFromEnv() (*Config, error) {
return nil, fmt.Errorf("invalid master seed: %s", err)
}

_, respondDirectly := os.LookupEnv(RESPOND_DIRECTLY)

log.Print("Loaded configuration:")
log.Printf(" - API_ENDPOINT: %s", showEmpty(apiEndpointStr))
log.Printf(" - API_CLIENT_ID: %s", showEmpty(apiClientId))
Expand All @@ -67,6 +71,7 @@ func NewConfigFromEnv() (*Config, error) {
ApiClientSecret: apiClientSecret,
WebhookSecret: webhookSecret,
MasterSeed: masterSeed,
RespondDirectly: respondDirectly,
}, nil
}

Expand Down
40 changes: 28 additions & 12 deletions examples/remote-signing-server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,37 @@ func main() {

switch event.EventType {
case objects.WebhookEventTypeRemoteSigning:
resp, err := remotesigning.HandleRemoteSigningWebhook(
lsClient, remotesigning.PositiveValidator{}, *event, config.MasterSeed)
if err != nil {
log.Printf("ERROR: Unable to handle remote signing webhook: %s", err)
c.AbortWithStatus(http.StatusInternalServerError)
return
}
if config.RespondDirectly {
resp, err := remotesigning.GraphQLResponseForRemoteSigningWebhook(
*event, config.MasterSeed)
if err != nil {
log.Printf("ERROR: Unable to handle remote signing webhook: %s", err)
c.AbortWithStatus(http.StatusInternalServerError)
return
}

if resp != "" {
log.Printf("Webhook complete with response: %s", resp)
if resp != nil {
c.JSON(http.StatusOK, resp.GraphqlResponse().Variables)
} else {
c.Status(http.StatusNoContent)
}
} else {
log.Printf("Webhook complete")
}
resp, err := remotesigning.HandleRemoteSigningWebhook(
lsClient, remotesigning.PositiveValidator{}, *event, config.MasterSeed)
if err != nil {
log.Printf("ERROR: Unable to handle remote signing webhook: %s", err)
c.AbortWithStatus(http.StatusInternalServerError)
return
}

c.Status(http.StatusNoContent)
if resp != "" {
log.Printf("Webhook complete with response: %s", resp)
} else {
log.Printf("Webhook complete")
}

c.Status(http.StatusNoContent)
}
default:
c.Status(http.StatusNoContent)
}
Expand Down
43 changes: 28 additions & 15 deletions remotesigning/remote_signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,54 @@ func HandleRemoteSigningWebhook(
webhook webhooks.WebhookEvent,
seedBytes []byte,
) (string, error) {
if !validator.ShouldSign(webhook) {
return DeclineToSignMessages(client, webhook)
}

response, err := GraphQLResponseForRemoteSigningWebhook(webhook, seedBytes)

if err != nil {
return "", err
}

if response == nil {
// No response is required for this event type.
return "", nil
}

return HandleSigningResponse(client, response)
}

func GraphQLResponseForRemoteSigningWebhook(
webhook webhooks.WebhookEvent,
seedBytes []byte,
) (SigningResponse, error) {
if webhook.EventType != objects.WebhookEventTypeRemoteSigning {
return "", errors.New("webhook event is not for remote signing")
return nil, errors.New("webhook event is not for remote signing")
}
if webhook.Data == nil {
return "", errors.New("webhook data is missing")
return nil, errors.New("webhook data is missing")
}
var subtype objects.RemoteSigningSubEventType
subEventTypeStr := (*webhook.Data)["sub_event_type"].(string)
log.Printf("Received remote signing webhook with sub_event_type %s", subEventTypeStr)
err := subtype.UnmarshalJSON([]byte(`"` + subEventTypeStr + `"`))
if err != nil {
return "", errors.New("invalid remote signing sub_event_type")
}

if !validator.ShouldSign(webhook) {
return DeclineToSignMessages(client, webhook)
return nil, errors.New("invalid remote signing sub_event_type")
}

request, err := ParseRemoteSigningRequest(webhook)
if err != nil {
return "", err
return nil, err
}

response, err := HandleSigningRequest(request, seedBytes)

if err != nil {
return "", err
}

if response == nil {
// No response is required for this event type.
return "", nil
return nil, err
}

return HandleSigningResponse(client, response)
return response, nil
}

func HandleSigningRequest(request SigningRequest, seedBytes []byte) (SigningResponse, error) {
Expand Down

0 comments on commit 1074ca1

Please sign in to comment.