Commit e7c15fc4 authored by ale's avatar ale

Simplify tests

Turn Server into a Client with a small interface wrapper.
parent 9cd4485b
......@@ -9,21 +9,25 @@ import (
"git.autistici.org/id/auth"
)
var defaultSocket = "/run/auth/socket"
var DefaultSocketPath = "/run/auth/socket"
type Client struct {
type Client interface {
Authenticate(context.Context, *auth.Request) (*auth.Response, error)
}
type socketClient struct {
socketPath string
codec auth.Codec
}
func New(socketPath string) *Client {
return &Client{
func New(socketPath string) Client {
return &socketClient{
socketPath: socketPath,
codec: auth.DefaultCodec,
}
}
func (c *Client) Authenticate(ctx context.Context, req *auth.Request) (*auth.Response, error) {
func (c *socketClient) Authenticate(ctx context.Context, req *auth.Request) (*auth.Response, error) {
conn, err := textproto.Dial("unix", c.socketPath)
if err != nil {
return nil, err
......
......@@ -26,6 +26,7 @@ type mapDecodable interface {
type kvCodec struct{}
// DefaultCodec is the codec used by the on-wire protocol.
var DefaultCodec = &kvCodec{}
//var charsToEscape = "\" \r\n"
......
......@@ -13,8 +13,10 @@ type DeviceInfo struct {
ID string
RemoteAddr string
RemoteZone string
UserAgent string
Browser string
OS string
Mobile bool
}
func (d *DeviceInfo) encodeToMap(m map[string]string, prefix string) {
......@@ -23,6 +25,12 @@ func (d *DeviceInfo) encodeToMap(m map[string]string, prefix string) {
m[prefix+"remote_zone"] = d.RemoteZone
m[prefix+"browser"] = d.Browser
m[prefix+"os"] = d.OS
m[prefix+"user_agent"] = d.UserAgent
if d.Mobile {
m[prefix+"mobile"] = "true"
} else {
m[prefix+"mobile"] = "false"
}
}
func decodeDeviceInfoFromMap(m map[string]string, prefix string) *DeviceInfo {
......@@ -35,6 +43,8 @@ func decodeDeviceInfoFromMap(m map[string]string, prefix string) *DeviceInfo {
RemoteZone: m[prefix+"remote_zone"],
Browser: m[prefix+"browser"],
OS: m[prefix+"os"],
UserAgent: m[prefix+"user_agent"],
Mobile: m[prefix+"mobile"] == "true",
}
}
......
......@@ -28,6 +28,8 @@ func TestProtocol_SerializeRequest(t *testing.T) {
RemoteZone: "cc",
Browser: "IE9",
OS: "Windows",
UserAgent: "MSIE/9.1 foo/12 bar/13",
Mobile: true,
},
}
......
......@@ -11,6 +11,7 @@ import (
"github.com/pquerna/otp/totp"
"git.autistici.org/id/auth"
"git.autistici.org/id/auth/client"
)
type testServer struct {
......@@ -51,8 +52,14 @@ func (s *testServer) Close() {
_ = os.RemoveAll(s.tmpdir)
}
type authClient interface {
Authenticate(context.Context, *auth.Request) *auth.Response
// A small adapter to make Server conform to the Client interface
// (Authenticate needs to return an error).
type clientAdapter struct {
*Server
}
func (c *clientAdapter) Authenticate(ctx context.Context, req *auth.Request) (*auth.Response, error) {
return c.Server.Authenticate(ctx, req), nil
}
var (
......@@ -84,7 +91,7 @@ services:
`
)
func runAuthenticationTest(t *testing.T, client authClient) {
func runAuthenticationTest(t *testing.T, client client.Client) {
// Test a number of simple password logins.
testdata := []struct {
service, username, password string
......@@ -97,11 +104,15 @@ func runAuthenticationTest(t *testing.T, client authClient) {
{"test", "2fauser", "password", auth.StatusError},
}
for _, td := range testdata {
resp := client.Authenticate(context.Background(), &auth.Request{
resp, err := client.Authenticate(context.Background(), &auth.Request{
Service: td.service,
Username: td.username,
Password: []byte(td.password),
})
if err != nil {
t.Errorf("transport error: %v", err)
continue
}
if resp.Status != td.expectedStatus {
t.Errorf("authentication error: s=%s u=%s p=%s, expected=%v got=%v", td.service, td.username, td.password, td.expectedStatus, resp.Status)
}
......@@ -122,12 +133,16 @@ func runAuthenticationTest(t *testing.T, client authClient) {
{"2fauser", "password", "123456", auth.StatusError, auth.TFAMethodNone},
}
for _, td := range testdata2 {
resp := client.Authenticate(context.Background(), &auth.Request{
resp, err := client.Authenticate(context.Background(), &auth.Request{
Service: "interactive",
Username: td.username,
OTP: td.otp,
Password: []byte(td.password),
})
if err != nil {
t.Errorf("transport error: %v", err)
continue
}
if resp.Status != td.expectedStatus {
t.Errorf("authentication error: s=interactive u=%s p=%s, expected=%v got=%v", td.username, td.password, td.expectedStatus, resp.Status)
}
......@@ -143,5 +158,5 @@ func TestAuthServer(t *testing.T) {
"config.yml": testConfigStr,
})
defer s.Close()
runAuthenticationTest(t, s.srv)
runAuthenticationTest(t, &clientAdapter{s.srv})
}
......@@ -13,22 +13,6 @@ import (
"git.autistici.org/id/auth/client"
)
// A small adapter to make auth.Client conform to the test
// 'authClient' interface: its Authenticate method returns an error,
// which we want to ignore.
type clientAdapter struct {
*client.Client
t testing.TB
}
func (c *clientAdapter) Authenticate(ctx context.Context, req *auth.Request) *auth.Response {
resp, err := c.Client.Authenticate(ctx, req)
if err != nil {
c.t.Fatal(err)
}
return resp
}
func TestAuthServer_UNIX(t *testing.T) {
s := createTestServer(t, map[string]string{
"users.yml": testUsersFileStr,
......@@ -44,8 +28,7 @@ func TestAuthServer_UNIX(t *testing.T) {
defer ss.Close()
c := client.New(".socket")
ad := &clientAdapter{c, t}
runAuthenticationTest(t, ad)
runAuthenticationTest(t, c)
}
func TestAuthServer_UNIX_ReuseSocket(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment