Skip to content

Commit

Permalink
feat: sms-login initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
splaunov committed Mar 1, 2022
1 parent 9d239d4 commit 41cef7e
Show file tree
Hide file tree
Showing 117 changed files with 3,090 additions and 335 deletions.
5 changes: 5 additions & 0 deletions cmd/clidoc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func init() {
"NewInfoSelfServiceRemoveWebAuthn": text.NewInfoSelfServiceRemoveWebAuthn("{name}", aSecondAgo),
"NewErrorValidationVerificationFlowExpired": text.NewErrorValidationVerificationFlowExpired(-time.Second),
"NewInfoSelfServiceVerificationSuccessful": text.NewInfoSelfServiceVerificationSuccessful(),
"NewInfoSelfServicePhoneVerificationSuccessful": text.NewInfoSelfServicePhoneVerificationSuccessful(),
"NewVerificationEmailSent": text.NewVerificationEmailSent(),
"NewErrorValidationVerificationTokenInvalidOrAlreadyUsed": text.NewErrorValidationVerificationTokenInvalidOrAlreadyUsed(),
"NewErrorValidationVerificationRetrySuccess": text.NewErrorValidationVerificationRetrySuccess(),
Expand Down Expand Up @@ -114,7 +115,11 @@ func init() {
"NewErrorValidationRecoveryTokenInvalidOrAlreadyUsed": text.NewErrorValidationRecoveryTokenInvalidOrAlreadyUsed(),
"NewErrorValidationRecoveryRetrySuccess": text.NewErrorValidationRecoveryRetrySuccess(),
"NewErrorValidationRecoveryStateFailure": text.NewErrorValidationRecoveryStateFailure(),
"NewErrorValidationInvalidCode": text.NewErrorValidationInvalidCode(),
"NewErrorCodeSent": text.NewErrorCodeSent(),
"NewInfoNodeInputEmail": text.NewInfoNodeInputEmail(),
"NewInfoNodeInputPhone": text.NewInfoNodeInputPhone(),
"NewVerificationPhoneSent": text.NewVerificationPhoneSent(),
}
}

Expand Down
14 changes: 11 additions & 3 deletions courier/courier.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package courier

//go:generate mockgen -destination=mocks/mock_courier.go -package=mocks github.com/ory/kratos/courier Courier

import (
"context"
"encoding/json"
Expand Down Expand Up @@ -81,9 +83,15 @@ func (c *courier) Work(ctx context.Context) error {

func (c *courier) watchMessages(ctx context.Context, errChan chan error) {
for {
if err := backoff.Retry(func() error {
return c.DispatchQueue(ctx)
}, backoff.NewExponentialBackOff()); err != nil {
if err := backoff.RetryNotify(
func() error {
return c.DispatchQueue(ctx)
},
backoff.NewExponentialBackOff(),
func(err error, t time.Duration) {
c.deps.Logger().WithError(err).Error("Courier DispatchQueue error")
},
); err != nil {
errChan <- err
return
}
Expand Down
1 change: 1 addition & 0 deletions courier/email_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
TypeVerificationValid TemplateType = "verification_valid"
TypeOTP TemplateType = "otp"
TypeTestStub TemplateType = "stub"
TypeCode TemplateType = "code"
)

type EmailTemplate interface {
Expand Down
96 changes: 96 additions & 0 deletions courier/mocks/mock_courier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions courier/sms.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"

"github.com/gofrs/uuid"
Expand Down Expand Up @@ -104,8 +106,15 @@ func (c *courier) dispatchSMS(ctx context.Context, msg Message) error {

defer res.Body.Close()

if res.StatusCode != http.StatusOK {
return errors.New(http.StatusText(res.StatusCode))
switch res.StatusCode {
case http.StatusOK:
case http.StatusCreated:
default:
b, err := io.ReadAll(res.Body)
if err != nil {
return err
}
return errors.New(fmt.Sprintf("Status: %s, body: %s", http.StatusText(res.StatusCode), string(b)))
}

return nil
Expand Down
8 changes: 8 additions & 0 deletions courier/sms_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func SMSTemplateType(t SMSTemplate) (TemplateType, error) {
return TypeOTP, nil
case *sms.TestStub:
return TypeTestStub, nil
case *sms.CodeMessage:
return TypeCode, nil
default:
return "", errors.Errorf("unexpected template type")
}
Expand All @@ -39,6 +41,12 @@ func NewSMSTemplateFromMessage(c Config, m Message) (SMSTemplate, error) {
return nil, err
}
return sms.NewTestStub(c, &t), nil
case TypeCode:
var t sms.CodeMessageModel
if err := json.Unmarshal(m.TemplateData, &t); err != nil {
return nil, err
}
return sms.NewCodeMessage(c, &t), nil
default:
return nil, errors.Errorf("received unexpected message template type: %s", m.TemplateType)
}
Expand Down
1 change: 1 addition & 0 deletions courier/sms_templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestNewSMSTemplateFromMessage(t *testing.T) {
for tmplType, expectedTmpl := range map[courier.TemplateType]courier.SMSTemplate{
courier.TypeOTP: sms.NewOTPMessage(conf, &sms.OTPMessageModel{To: "+12345678901"}),
courier.TypeTestStub: sms.NewTestStub(conf, &sms.TestStubModel{To: "+12345678901", Body: "test body"}),
courier.TypeCode: sms.NewCodeMessage(conf, &sms.CodeMessageModel{To: "+12345678901"}),
} {
t.Run(fmt.Sprintf("case=%s", tmplType), func(t *testing.T) {
tmplData, err := json.Marshal(expectedTmpl)
Expand Down
4 changes: 2 additions & 2 deletions courier/sms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ func TestQueueSMS(t *testing.T) {
expectedSMS := []*sms.TestStubModel{
{
To: "+12065550101",
Body: "test-sms-body-1",
Body: "test-code-body-1",
},
{
To: "+12065550102",
Body: "test-sms-body-2",
Body: "test-code-body-2",
},
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
code {{ .Code }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
stub sms body {{ .Body }}
34 changes: 34 additions & 0 deletions courier/template/sms/code_login.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package sms

import (
"encoding/json"
"github.com/ory/kratos/courier/template"
"os"
)

type (
CodeMessage struct {
c template.Config
m *CodeMessageModel
}
CodeMessageModel struct {
To string
Code string
}
)

func NewCodeMessage(c template.Config, m *CodeMessageModel) *CodeMessage {
return &CodeMessage{c: c, m: m}
}

func (t *CodeMessage) PhoneNumber() (string, error) {
return t.m.To, nil
}

func (t *CodeMessage) SMSBody() (string, error) {
return template.LoadText(os.DirFS(t.c.CourierTemplatesRoot()), "login/sms.body.gotmpl", "login/sms.body*", t.m)
}

func (t *CodeMessage) MarshalJSON() ([]byte, error) {
return json.Marshal(t.m)
}
35 changes: 35 additions & 0 deletions courier/template/sms/sms_stub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package sms

import (
"encoding/json"
"github.com/ory/kratos/courier/template"
"os"

"github.com/ory/kratos/driver/config"
)

type TestSmsStub struct {
c *config.Config
m *TestSmsStubModel
}

type TestSmsStubModel struct {
Phone string
Body string
}

func NewTestSmsStub(c *config.Config, m *TestSmsStubModel) *TestSmsStub {
return &TestSmsStub{c: c, m: m}
}

func (t *TestSmsStub) SmsRecipientPhone() (string, error) {
return t.m.Phone, nil
}

func (t *TestSmsStub) SmsBody() (string, error) {
return template.LoadText(os.DirFS(t.c.CourierTemplatesRoot()), "test_stub/sms.body.gotmpl", "test_stub/sms.body*", t.m)
}

func (t *TestSmsStub) MarshalJSON() ([]byte, error) {
return json.Marshal(t.m)
}
2 changes: 1 addition & 1 deletion docs/docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2442,7 +2442,7 @@ clients:

## Courier configuration ##
#
# The courier is responsible for sending and delivering messages over email, sms, and other means.
# The courier is responsible for sending and delivering messages over email, code, and other means.
#
courier:
## SMTP Configuration ##
Expand Down
Loading

0 comments on commit 41cef7e

Please sign in to comment.