2024-03-05 17:37:54 +05:30
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
)
|
|
|
|
|
|
|
|
type SignerMock struct {
|
|
|
|
mock.Mock
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *SignerMock) Sign(data io.Reader) ([]byte, error) {
|
|
|
|
args := m.Called(data)
|
|
|
|
var result []byte
|
|
|
|
if casted, ok := args.Get(0).([]byte); ok {
|
|
|
|
result = casted
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, args.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *SignerMock) GetPublicKey(format string) ([]byte, error) {
|
|
|
|
args := m.Called(format)
|
|
|
|
var result []byte
|
|
|
|
if casted, ok := args.Get(0).([]byte); ok {
|
|
|
|
result = casted
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, args.Error(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
type SignerApiTestSuite struct {
|
|
|
|
suite.Suite
|
|
|
|
|
|
|
|
App *SignerApi
|
|
|
|
|
|
|
|
Signer *SignerMock
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *SignerApiTestSuite) SetupSubTest() {
|
|
|
|
t.Signer = &SignerMock{}
|
|
|
|
|
2024-03-13 05:59:26 +05:30
|
|
|
t.App, _ = NewSignerApi(t.Signer)
|
2024-03-05 17:37:54 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
func (t *SignerApiTestSuite) TearDownSubTest() {
|
|
|
|
t.Signer.AssertExpectations(t.T())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *SignerApiTestSuite) TestSign() {
|
|
|
|
t.Run("successfully sign", func() {
|
|
|
|
signature := []byte("mock signature")
|
|
|
|
t.Signer.On("Sign", mock.Anything).Return(signature, nil).Run(func(args mock.Arguments) {
|
|
|
|
buf := &bytes.Buffer{}
|
|
|
|
_, _ = io.Copy(buf, args.Get(0).(io.Reader))
|
|
|
|
r, _ := io.ReadAll(buf)
|
|
|
|
|
|
|
|
t.Equal([]byte("mock body to sign"), r)
|
|
|
|
})
|
|
|
|
|
|
|
|
req := httptest.NewRequest("POST", "http://chrly/", strings.NewReader("mock body to sign"))
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
|
|
|
|
result := w.Result()
|
|
|
|
t.Equal(http.StatusOK, result.StatusCode)
|
|
|
|
t.Equal("application/octet-stream+base64", result.Header.Get("Content-Type"))
|
|
|
|
body, _ := io.ReadAll(result.Body)
|
|
|
|
t.Equal([]byte{0x62, 0x57, 0x39, 0x6a, 0x61, 0x79, 0x42, 0x7a, 0x61, 0x57, 0x64, 0x75, 0x59, 0x58, 0x52, 0x31, 0x63, 0x6d, 0x55, 0x3d}, body)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("handle error during sign", func() {
|
|
|
|
t.Signer.On("Sign", mock.Anything).Return(nil, errors.New("mock error"))
|
|
|
|
|
|
|
|
req := httptest.NewRequest("POST", "http://chrly/", strings.NewReader("mock body to sign"))
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
|
|
|
|
result := w.Result()
|
|
|
|
t.Equal(http.StatusInternalServerError, result.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *SignerApiTestSuite) TestGetPublicKey() {
|
|
|
|
t.Run("in pem format", func() {
|
|
|
|
publicKey := []byte("mock public key in pem format")
|
|
|
|
t.Signer.On("GetPublicKey", "pem").Return(publicKey, nil)
|
|
|
|
|
|
|
|
req := httptest.NewRequest("GET", "http://chrly/public-key.pem", nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
|
|
|
|
result := w.Result()
|
|
|
|
t.Equal(http.StatusOK, result.StatusCode)
|
|
|
|
t.Equal("application/x-pem-file", result.Header.Get("Content-Type"))
|
|
|
|
t.Equal(`attachment; filename="yggdrasil_session_pubkey.pem"`, result.Header.Get("Content-Disposition"))
|
|
|
|
body, _ := io.ReadAll(result.Body)
|
|
|
|
t.Equal(publicKey, body)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("in der format", func() {
|
|
|
|
publicKey := []byte("mock public key in der format")
|
|
|
|
t.Signer.On("GetPublicKey", "der").Return(publicKey, nil)
|
|
|
|
|
|
|
|
req := httptest.NewRequest("GET", "http://chrly/public-key.der", nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
|
|
|
|
result := w.Result()
|
|
|
|
t.Equal(http.StatusOK, result.StatusCode)
|
|
|
|
t.Equal("application/octet-stream", result.Header.Get("Content-Type"))
|
|
|
|
t.Equal(`attachment; filename="yggdrasil_session_pubkey.der"`, result.Header.Get("Content-Disposition"))
|
|
|
|
body, _ := io.ReadAll(result.Body)
|
|
|
|
t.Equal(publicKey, body)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("handle error", func() {
|
|
|
|
t.Signer.On("GetPublicKey", "pem").Return(nil, errors.New("mock error"))
|
|
|
|
|
|
|
|
req := httptest.NewRequest("GET", "http://chrly/public-key.pem", nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
|
|
|
|
result := w.Result()
|
|
|
|
t.Equal(http.StatusInternalServerError, result.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSignerApi(t *testing.T) {
|
|
|
|
suite.Run(t, new(SignerApiTestSuite))
|
|
|
|
}
|