mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-12-03 19:26:50 +02:00
588 lines
20 KiB
Go
588 lines
20 KiB
Go
package apis_test
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/pocketbase/pocketbase/tests"
|
|
)
|
|
|
|
func TestSettingsList(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "unauthorized",
|
|
Method: http.MethodGet,
|
|
URL: "/api/settings",
|
|
ExpectedStatus: 401,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as regular user",
|
|
Method: http.MethodGet,
|
|
URL: "/api/settings",
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo",
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser",
|
|
Method: http.MethodGet,
|
|
URL: "/api/settings",
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{
|
|
`"meta":{`,
|
|
`"logs":{`,
|
|
`"smtp":{`,
|
|
`"s3":{`,
|
|
`"backups":{`,
|
|
`"batch":{`,
|
|
},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnSettingsListRequest": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestSettingsSet(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
validData := `{
|
|
"meta":{"appName":"update_test"},
|
|
"s3":{"secret": "s3_secret"},
|
|
"backups":{"s3":{"secret":"backups_s3_secret"}}
|
|
}`
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "unauthorized",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/settings",
|
|
Body: strings.NewReader(validData),
|
|
ExpectedStatus: 401,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as regular user",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/settings",
|
|
Body: strings.NewReader(validData),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo",
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser submitting empty data",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/settings",
|
|
Body: strings.NewReader(``),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{
|
|
`"meta":{`,
|
|
`"logs":{`,
|
|
`"smtp":{`,
|
|
`"s3":{`,
|
|
`"backups":{`,
|
|
`"batch":{`,
|
|
},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnSettingsUpdateRequest": 1,
|
|
"OnModelUpdate": 1,
|
|
"OnModelUpdateExecute": 1,
|
|
"OnModelAfterUpdateSuccess": 1,
|
|
"OnModelValidate": 1,
|
|
"OnSettingsReload": 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "authorized as superuser submitting invalid data",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/settings",
|
|
Body: strings.NewReader(`{"meta":{"appName":""}}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{
|
|
`"data":{`,
|
|
`"meta":{"appName":{"code":"validation_required"`,
|
|
},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnModelUpdate": 1,
|
|
"OnModelAfterUpdateError": 1,
|
|
"OnModelValidate": 1,
|
|
"OnSettingsUpdateRequest": 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "authorized as superuser submitting valid data",
|
|
Method: http.MethodPatch,
|
|
URL: "/api/settings",
|
|
Body: strings.NewReader(validData),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{
|
|
`"meta":{`,
|
|
`"logs":{`,
|
|
`"smtp":{`,
|
|
`"s3":{`,
|
|
`"backups":{`,
|
|
`"batch":{`,
|
|
`"appName":"update_test"`,
|
|
},
|
|
NotExpectedContent: []string{
|
|
"secret",
|
|
"password",
|
|
},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnSettingsUpdateRequest": 1,
|
|
"OnModelUpdate": 1,
|
|
"OnModelUpdateExecute": 1,
|
|
"OnModelAfterUpdateSuccess": 1,
|
|
"OnModelValidate": 1,
|
|
"OnSettingsReload": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestSettingsTestS3(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "unauthorized",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/s3",
|
|
ExpectedStatus: 401,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as regular user",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/s3",
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo",
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (missing body + no s3)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/s3",
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{
|
|
`"data":{`,
|
|
`"filesystem":{`,
|
|
},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (invalid filesystem)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/s3",
|
|
Body: strings.NewReader(`{"filesystem":"invalid"}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{
|
|
`"data":{`,
|
|
`"filesystem":{`,
|
|
},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (valid filesystem and no s3)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/s3",
|
|
Body: strings.NewReader(`{"filesystem":"storage"}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{
|
|
`"data":{}`,
|
|
},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestSettingsTestEmail(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "unauthorized",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{
|
|
"template": "verification",
|
|
"email": "test@example.com"
|
|
}`),
|
|
ExpectedStatus: 401,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as regular user",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{
|
|
"template": "verification",
|
|
"email": "test@example.com"
|
|
}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo",
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (invalid body)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (empty json)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{
|
|
`"email":{"code":"validation_required"`,
|
|
`"template":{"code":"validation_required"`,
|
|
},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (verifiation template)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{
|
|
"template": "verification",
|
|
"email": "test@example.com"
|
|
}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
AfterTestFunc: func(t testing.TB, app *tests.TestApp, res *http.Response) {
|
|
if app.TestMailer.TotalSend() != 1 {
|
|
t.Fatalf("[verification] Expected 1 sent email, got %d", app.TestMailer.TotalSend())
|
|
}
|
|
|
|
if len(app.TestMailer.LastMessage().To) != 1 {
|
|
t.Fatalf("[verification] Expected 1 recipient, got %v", app.TestMailer.LastMessage().To)
|
|
}
|
|
|
|
if app.TestMailer.LastMessage().To[0].Address != "test@example.com" {
|
|
t.Fatalf("[verification] Expected the email to be sent to %s, got %s", "test@example.com", app.TestMailer.LastMessage().To[0].Address)
|
|
}
|
|
|
|
if !strings.Contains(app.TestMailer.LastMessage().HTML, "Verify") {
|
|
t.Fatalf("[verification] Expected to sent a verification email, got \n%v\n%v", app.TestMailer.LastMessage().Subject, app.TestMailer.LastMessage().HTML)
|
|
}
|
|
},
|
|
ExpectedStatus: 204,
|
|
ExpectedContent: []string{},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnMailerSend": 1,
|
|
"OnMailerRecordVerificationSend": 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (password reset template)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{
|
|
"template": "password-reset",
|
|
"email": "test@example.com"
|
|
}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
AfterTestFunc: func(t testing.TB, app *tests.TestApp, res *http.Response) {
|
|
if app.TestMailer.TotalSend() != 1 {
|
|
t.Fatalf("[password-reset] Expected 1 sent email, got %d", app.TestMailer.TotalSend())
|
|
}
|
|
|
|
if len(app.TestMailer.LastMessage().To) != 1 {
|
|
t.Fatalf("[password-reset] Expected 1 recipient, got %v", app.TestMailer.LastMessage().To)
|
|
}
|
|
|
|
if app.TestMailer.LastMessage().To[0].Address != "test@example.com" {
|
|
t.Fatalf("[password-reset] Expected the email to be sent to %s, got %s", "test@example.com", app.TestMailer.LastMessage().To[0].Address)
|
|
}
|
|
|
|
if !strings.Contains(app.TestMailer.LastMessage().HTML, "Reset password") {
|
|
t.Fatalf("[password-reset] Expected to sent a password-reset email, got \n%v\n%v", app.TestMailer.LastMessage().Subject, app.TestMailer.LastMessage().HTML)
|
|
}
|
|
},
|
|
ExpectedStatus: 204,
|
|
ExpectedContent: []string{},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnMailerSend": 1,
|
|
"OnMailerRecordPasswordResetSend": 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (email change)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{
|
|
"template": "email-change",
|
|
"email": "test@example.com"
|
|
}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
AfterTestFunc: func(t testing.TB, app *tests.TestApp, res *http.Response) {
|
|
if app.TestMailer.TotalSend() != 1 {
|
|
t.Fatalf("[email-change] Expected 1 sent email, got %d", app.TestMailer.TotalSend())
|
|
}
|
|
|
|
if len(app.TestMailer.LastMessage().To) != 1 {
|
|
t.Fatalf("[email-change] Expected 1 recipient, got %v", app.TestMailer.LastMessage().To)
|
|
}
|
|
|
|
if app.TestMailer.LastMessage().To[0].Address != "test@example.com" {
|
|
t.Fatalf("[email-change] Expected the email to be sent to %s, got %s", "test@example.com", app.TestMailer.LastMessage().To[0].Address)
|
|
}
|
|
|
|
if !strings.Contains(app.TestMailer.LastMessage().HTML, "Confirm new email") {
|
|
t.Fatalf("[email-change] Expected to sent a confirm new email email, got \n%v\n%v", app.TestMailer.LastMessage().Subject, app.TestMailer.LastMessage().HTML)
|
|
}
|
|
},
|
|
ExpectedStatus: 204,
|
|
ExpectedContent: []string{},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnMailerSend": 1,
|
|
"OnMailerRecordEmailChangeSend": 1,
|
|
},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (otp)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/test/email",
|
|
Body: strings.NewReader(`{
|
|
"template": "otp",
|
|
"email": "test@example.com"
|
|
}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
AfterTestFunc: func(t testing.TB, app *tests.TestApp, res *http.Response) {
|
|
if app.TestMailer.TotalSend() != 1 {
|
|
t.Fatalf("[otp] Expected 1 sent email, got %d", app.TestMailer.TotalSend())
|
|
}
|
|
|
|
if len(app.TestMailer.LastMessage().To) != 1 {
|
|
t.Fatalf("[otp] Expected 1 recipient, got %v", app.TestMailer.LastMessage().To)
|
|
}
|
|
|
|
if app.TestMailer.LastMessage().To[0].Address != "test@example.com" {
|
|
t.Fatalf("[otp] Expected the email to be sent to %s, got %s", "test@example.com", app.TestMailer.LastMessage().To[0].Address)
|
|
}
|
|
|
|
if !strings.Contains(app.TestMailer.LastMessage().HTML, "one-time password") {
|
|
t.Fatalf("[otp] Expected to sent OTP email, got \n%v\n%v", app.TestMailer.LastMessage().Subject, app.TestMailer.LastMessage().HTML)
|
|
}
|
|
},
|
|
ExpectedStatus: 204,
|
|
ExpectedContent: []string{},
|
|
ExpectedEvents: map[string]int{
|
|
"*": 0,
|
|
"OnMailerSend": 1,
|
|
"OnMailerRecordOTPSend": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|
|
|
|
func TestGenerateAppleClientSecret(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
encodedKey, err := x509.MarshalPKCS8PrivateKey(key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
privatePem := pem.EncodeToMemory(
|
|
&pem.Block{
|
|
Type: "PRIVATE KEY",
|
|
Bytes: encodedKey,
|
|
},
|
|
)
|
|
|
|
scenarios := []tests.ApiScenario{
|
|
{
|
|
Name: "unauthorized",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/apple/generate-client-secret",
|
|
ExpectedStatus: 401,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as regular user",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/apple/generate-client-secret",
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo",
|
|
},
|
|
ExpectedStatus: 403,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (invalid body)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/apple/generate-client-secret",
|
|
Body: strings.NewReader(`{`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{`"data":{}`},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (empty json)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/apple/generate-client-secret",
|
|
Body: strings.NewReader(`{}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{
|
|
`"clientId":{"code":"validation_required"`,
|
|
`"teamId":{"code":"validation_required"`,
|
|
`"keyId":{"code":"validation_required"`,
|
|
`"privateKey":{"code":"validation_required"`,
|
|
`"duration":{"code":"validation_required"`,
|
|
},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (invalid data)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/apple/generate-client-secret",
|
|
Body: strings.NewReader(`{
|
|
"clientId": "",
|
|
"teamId": "123456789",
|
|
"keyId": "123456789",
|
|
"privateKey": "invalid",
|
|
"duration": -1
|
|
}`),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 400,
|
|
ExpectedContent: []string{
|
|
`"clientId":{"code":"validation_required"`,
|
|
`"teamId":{"code":"validation_length_invalid"`,
|
|
`"keyId":{"code":"validation_length_invalid"`,
|
|
`"privateKey":{"code":"validation_match_invalid"`,
|
|
`"duration":{"code":"validation_min_greater_equal_than_required"`,
|
|
},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
{
|
|
Name: "authorized as superuser (valid data)",
|
|
Method: http.MethodPost,
|
|
URL: "/api/settings/apple/generate-client-secret",
|
|
Body: strings.NewReader(fmt.Sprintf(`{
|
|
"clientId": "123",
|
|
"teamId": "1234567890",
|
|
"keyId": "1234567891",
|
|
"privateKey": %q,
|
|
"duration": 1
|
|
}`, privatePem)),
|
|
Headers: map[string]string{
|
|
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
|
|
},
|
|
ExpectedStatus: 200,
|
|
ExpectedContent: []string{
|
|
`"secret":"`,
|
|
},
|
|
ExpectedEvents: map[string]int{"*": 0},
|
|
},
|
|
}
|
|
|
|
for _, scenario := range scenarios {
|
|
scenario.Test(t)
|
|
}
|
|
}
|