mirror of
https://github.com/volatiletech/authboss.git
synced 2024-11-28 08:58:38 +02:00
c89ca29827
I have a feeling that I wrote all this fanciness in when the user was still able to fetch himself from the database. But since that's been dropped I don't think any of this stuff is necessary. In terms of setting without an error, we should do validation before an attempt to save, not every time we set a field. This will just end up being much nicer error handling, and the database is going to do it's own validation and we can handle that error in the same way.
169 lines
3.5 KiB
Go
169 lines
3.5 KiB
Go
package authboss
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
type mockUser struct {
|
|
Email string
|
|
Password string
|
|
}
|
|
|
|
type mockServerStorer map[string]mockUser
|
|
|
|
func (m mockServerStorer) Load(ctx context.Context, key string) (User, error) {
|
|
u, ok := m[key]
|
|
if !ok {
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
return u, nil
|
|
}
|
|
|
|
func (m mockServerStorer) Save(ctx context.Context, user User) error {
|
|
pid := user.GetPID()
|
|
m[pid] = user.(mockUser)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m mockUser) PutPID(email string) {
|
|
m.Email = email
|
|
}
|
|
|
|
func (m mockUser) PutPassword(password string) {
|
|
m.Password = password
|
|
}
|
|
|
|
func (m mockUser) GetPID() (email string) {
|
|
return m.Email
|
|
}
|
|
|
|
func (m mockUser) GetPassword() (password string) {
|
|
return m.Password
|
|
}
|
|
|
|
type mockClientStateReadWriter struct {
|
|
state mockClientState
|
|
}
|
|
|
|
type mockClientState map[string]string
|
|
|
|
func newMockClientStateRW(keyValue ...string) mockClientStateReadWriter {
|
|
state := mockClientState{}
|
|
for i := 0; i < len(keyValue); i += 2 {
|
|
key, value := keyValue[i], keyValue[i+1]
|
|
state[key] = value
|
|
}
|
|
|
|
return mockClientStateReadWriter{state}
|
|
}
|
|
|
|
func (m mockClientStateReadWriter) ReadState(w http.ResponseWriter, r *http.Request) (ClientState, error) {
|
|
return m.state, nil
|
|
}
|
|
|
|
func (m mockClientStateReadWriter) WriteState(w http.ResponseWriter, cs ClientState, evs []ClientStateEvent) error {
|
|
var state mockClientState
|
|
|
|
if cs != nil {
|
|
state = cs.(mockClientState)
|
|
} else {
|
|
state = mockClientState{}
|
|
}
|
|
|
|
for _, ev := range evs {
|
|
switch ev.Kind {
|
|
case ClientStateEventPut:
|
|
state[ev.Key] = ev.Value
|
|
case ClientStateEventDel:
|
|
delete(state, ev.Key)
|
|
}
|
|
}
|
|
|
|
b, err := json.Marshal(state)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
w.Header().Set("test_session", string(b))
|
|
return nil
|
|
}
|
|
|
|
func (m mockClientState) Get(key string) (string, bool) {
|
|
val, ok := m[key]
|
|
return val, ok
|
|
}
|
|
|
|
func newMockRequest(postKeyValues ...string) *http.Request {
|
|
urlValues := make(url.Values)
|
|
for i := 0; i < len(postKeyValues); i += 2 {
|
|
urlValues.Set(postKeyValues[i], postKeyValues[i+1])
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", "http://localhost", strings.NewReader(urlValues.Encode()))
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
return req
|
|
}
|
|
|
|
func newMockAPIRequest(postKeyValues ...string) *http.Request {
|
|
kv := map[string]string{}
|
|
for i := 0; i < len(postKeyValues); i += 2 {
|
|
key, value := postKeyValues[i], postKeyValues[i+1]
|
|
kv[key] = value
|
|
}
|
|
|
|
b, err := json.Marshal(kv)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", "http://localhost", bytes.NewReader(b))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
return req
|
|
}
|
|
|
|
type mockRenderer struct {
|
|
expectName string
|
|
}
|
|
|
|
func (m mockRenderer) Load(names ...string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m mockRenderer) Render(ctx context.Context, name string, data HTMLData) ([]byte, string, error) {
|
|
if len(m.expectName) != 0 && m.expectName != name {
|
|
panic(fmt.Sprintf("want template name: %s, but got: %s", m.expectName, name))
|
|
}
|
|
|
|
b, err := json.Marshal(data)
|
|
return b, "application/json", err
|
|
}
|
|
|
|
type mockEmailRenderer struct{}
|
|
|
|
func (m mockEmailRenderer) Render(ctx context.Context, name string, data HTMLData) ([]byte, string, error) {
|
|
switch name {
|
|
case "text":
|
|
return []byte("a development text e-mail template"), "text/plain", nil
|
|
case "html":
|
|
return []byte("a development html e-mail template"), "text/html", nil
|
|
default:
|
|
panic("shouldn't get here")
|
|
}
|
|
}
|