Skip to content

Commit

Permalink
Support Twilio API key
Browse files Browse the repository at this point in the history
  • Loading branch information
chankiyu22 authored Oct 10, 2024
2 parents fb3d4a7 + 60ad075 commit 2564136
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 33 deletions.
40 changes: 31 additions & 9 deletions pkg/lib/config/sms_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,16 @@ type Provider struct {
}

type ProviderConfigTwilio struct {
AccountSID string `json:"account_sid,omitempty"`

// From and MessagingServiceSID are mutually exclusive.
From string `json:"from,omitempty"`
AccountSID string `json:"account_sid,omitempty"`
AuthToken string `json:"auth_token,omitempty"`
MessagingServiceSID string `json:"messaging_service_sid,omitempty"`

// AuthToken and (APIKey and APIKeySecret) are mutually exclusive.
AuthToken string `json:"auth_token,omitempty"`
APIKey string `json:"api_key,omitempty"`
APIKeySecret string `json:"api_key_secret,omitempty"`
}

type ProviderConfigAccessYou struct {
Expand Down Expand Up @@ -83,18 +89,34 @@ var _ = RootSchema.Add("ProviderConfigTwilio", `
"type": "object",
"additionalProperties": false,
"properties": {
"from": { "type": "string" },
"account_sid": { "type": "string" },
"auth_token": {"type": "string"},
"messaging_service_sid": {"type": "string"}
"from": { "type": "string" },
"messaging_service_sid": { "type": "string" },
"auth_token": { "type": "string" },
"api_key": { "type": "string" },
"api_key_secret": { "type": "string" }
},
"required": ["account_sid", "auth_token"],
"oneOf": [
"required": ["account_sid"],
"allOf": [
{
"required": ["from"]
"oneOf": [
{
"required": ["from"]
},
{
"required": ["messaging_service_sid"]
}
]
},
{
"required": ["messaging_service_sid"]
"oneOf": [
{
"required": ["auth_token"]
},
{
"required": ["api_key", "api_key_secret"]
}
]
}
]
}
Expand Down
83 changes: 82 additions & 1 deletion pkg/lib/config/testdata/authgear-sms-gateway.tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ config:
- type: default
use_provider: twilio
---
name: failed-twilio-config
name: twilio-both-from-and-messaging-service-sid-present
error: |-
invalid configuration:
/providers/0/twilio: oneOf
Expand All @@ -232,6 +232,87 @@ config:
- type: default
use_provider: twilio
---
name: twilio-both-auth-token-and-api-key-present
error: |-
invalid configuration:
/providers/0/twilio: oneOf
config:
providers:
- name: twilio
type: twilio
twilio:
account_sid: "my-account-sid"
messaging_service_sid: "my-messaging-service-sid"
auth_token: "my-auth-token"
api_key: "api-key"
api_key_secret: "api-key-secret"
provider_selector:
switch:
- type: default
use_provider: twilio
---
name: twilio-auth-token-from
error: null
config:
providers:
- name: twilio
type: twilio
twilio:
account_sid: "my-account-sid"
from: "sender"
auth_token: "my-auth-token"
provider_selector:
switch:
- type: default
use_provider: twilio
---
name: twilio-auth-token-messaging-service-sid
error: null
config:
providers:
- name: twilio
type: twilio
twilio:
account_sid: "my-account-sid"
messaging_service_sid: "messaging_service_sid"
auth_token: "my-auth-token"
provider_selector:
switch:
- type: default
use_provider: twilio
---
name: twilio-api-key-from
error: null
config:
providers:
- name: twilio
type: twilio
twilio:
account_sid: "my-account-sid"
from: "sender"
api_key: "api-key"
api_key_secret: "api-key-secret"
provider_selector:
switch:
- type: default
use_provider: twilio
---
name: twilio-api-key-messaging-service-sid
error: null
config:
providers:
- name: twilio
type: twilio
twilio:
account_sid: "my-account-sid"
messaging_service_sid: "messaging-service-sid"
api_key: "api-key"
api_key_secret: "api-key-secret"
provider_selector:
switch:
- type: default
use_provider: twilio
---
name: missing-required-fields-in-switch-cases
error: |-
invalid configuration:
Expand Down
18 changes: 10 additions & 8 deletions pkg/lib/sms/smsclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ import (
func NewClientFromConfigProvider(p *config.Provider, httpClient *http.Client, logger *slog.Logger) smsclient.RawClient {
switch p.Type {
case config.ProviderTypeTwilio:
return twilio.NewTwilioClient(
httpClient,
p.Twilio.AccountSID,
p.Twilio.AuthToken,
p.Twilio.From,
p.Twilio.MessagingServiceSID,
logger,
)
return &twilio.TwilioClient{
Client: httpClient,
AccountSID: p.Twilio.AccountSID,
AuthToken: p.Twilio.AuthToken,
APIKey: p.Twilio.APIKey,
APIKeySecret: p.Twilio.APIKeySecret,
From: p.Twilio.From,
MessagingServiceSID: p.Twilio.MessagingServiceSID,
Logger: logger,
}
case config.ProviderTypeAccessYou:
return accessyou.NewAccessYouClient(
httpClient,
Expand Down
37 changes: 22 additions & 15 deletions pkg/lib/sms/twilio/smsclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,18 @@ import (
)

type TwilioClient struct {
Client *http.Client
AccountSID string
AuthToken string
Client *http.Client

AccountSID string

AuthToken string
APIKey string
APIKeySecret string

From string
MessagingServiceSID string
Logger *slog.Logger
}

func NewTwilioClient(httpClient *http.Client, accountSID string, authToken string, from string, messagingServiceSID string, logger *slog.Logger) *TwilioClient {
return &TwilioClient{
Client: httpClient,
AccountSID: accountSID,
AuthToken: authToken,
From: from,
MessagingServiceSID: messagingServiceSID,
Logger: logger,
}
Logger *slog.Logger
}

func (t *TwilioClient) send(options *smsclient.SendOptions) ([]byte, *SendResponse, error) {
Expand All @@ -56,7 +51,19 @@ func (t *TwilioClient) send(options *smsclient.SendOptions) ([]byte, *SendRespon

requestBody := values.Encode()
req, _ := http.NewRequest("POST", u.String(), strings.NewReader(requestBody))
req.SetBasicAuth(t.AccountSID, t.AuthToken)

// https://www.twilio.com/docs/usage/api#authenticate-with-http
if t.AuthToken != "" {
// When Auth Token is used, username is Account SID, and password is Auth Token.
req.SetBasicAuth(t.AccountSID, t.AuthToken)
} else if t.APIKey != "" {
// When API Key is used, username is API key, and password is API key secret.
req.SetBasicAuth(t.APIKey, t.APIKeySecret)
} else { //nolint: staticcheck
// Normally we should not reach here.
// But in case we do, we do not provide the auth header.
// And Twilio should returns an error response to us in this case.
}

resp, err := t.Client.Do(req)
if err != nil {
Expand Down

0 comments on commit 2564136

Please sign in to comment.