| package wspr |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "fmt" |
| "net/http" |
| "net/http/httptest" |
| "testing" |
| "time" |
| |
| "veyron.io/veyron/veyron2/context" |
| "veyron.io/veyron/veyron2/ipc" |
| "veyron.io/veyron/veyron2/security" |
| "veyron.io/veyron/veyron2/vdl/vdlutil" |
| ) |
| |
| // BEGIN MOCK BLESSER SERVICE |
| // TODO(nlacasse): Is there a better way to mock this?! |
| type mockBlesserService struct { |
| id security.PrivateID |
| count int |
| } |
| |
| func newMockBlesserService(id security.PrivateID) *mockBlesserService { |
| return &mockBlesserService{ |
| id: id, |
| count: 0, |
| } |
| } |
| |
| func (m *mockBlesserService) BlessUsingAccessToken(c context.T, accessToken string, co ...ipc.CallOpt) (vdlutil.Any, error) { |
| m.count = m.count + 1 |
| name := fmt.Sprintf("mock-blessing-%v", m.count) |
| return m.id.Bless(m.id.PublicID(), name, 5*time.Minute, nil) |
| } |
| |
| // This is never used. Only needed for mock. |
| func (m *mockBlesserService) GetMethodTags(c context.T, s string, co ...ipc.CallOpt) ([]interface{}, error) { |
| return nil, nil |
| } |
| |
| // This is never used. Only needed for mock. |
| func (m *mockBlesserService) Signature(c context.T, co ...ipc.CallOpt) (ipc.ServiceSignature, error) { |
| return ipc.ServiceSignature{}, nil |
| } |
| |
| // This is never used. Only needed for mock. |
| func (m *mockBlesserService) UnresolveStep(c context.T, co ...ipc.CallOpt) ([]string, error) { |
| return []string{}, nil |
| } |
| |
| // END MOCK BLESSER SERVICE |
| |
| func setup(t *testing.T) (*WSPR, func()) { |
| wspr := NewWSPR(0, "/mock/proxy", "/mock/identd") |
| providerId := wspr.rt.Identity() |
| |
| wspr.blesserService = newMockBlesserService(providerId) |
| return wspr, func() { |
| wspr.Shutdown() |
| } |
| } |
| |
| func TestHandleCreateAccount(t *testing.T) { |
| wspr, teardown := setup(t) |
| defer teardown() |
| |
| method := "POST" |
| path := "/create-account" |
| |
| // Add one account |
| data1 := createAccountInput{ |
| AccessToken: "mock-access-token-1", |
| } |
| data1Json, err := json.Marshal(data1) |
| if err != nil { |
| t.Fatalf("json.Marshal(%v) failed: %v", data1, err) |
| } |
| |
| data1JsonReader := bytes.NewReader(data1Json) |
| req, err := http.NewRequest(method, path, (data1JsonReader)) |
| if err != nil { |
| t.Fatalf("http.NewRequest(%v, %v, %v,) failed: %v", method, path, data1JsonReader, err) |
| } |
| |
| resp1 := httptest.NewRecorder() |
| wspr.handleCreateAccount(resp1, req) |
| if resp1.Code != 200 { |
| t.Fatalf("Expected handleCreateAccount to return 200 OK, instead got %v", resp1) |
| } |
| |
| // Verify that idManager has the new account |
| topLevelName := wspr.rt.Identity().PublicID().Names()[0] |
| expectedAccountName := topLevelName + "/mock-blessing-1" |
| gotAccounts := wspr.idManager.AccountsMatching(security.BlessingPattern(expectedAccountName)) |
| if len(gotAccounts) != 1 { |
| t.Fatalf("Expected to have 1 account with name %v, but got %v: %v", expectedAccountName, len(gotAccounts), gotAccounts) |
| } |
| |
| // Add another account |
| data2 := createAccountInput{ |
| AccessToken: "mock-access-token-2", |
| } |
| data2Json, err := json.Marshal(data2) |
| if err != nil { |
| t.Fatalf("json.Marshal(%v) failed: %v", data2, err) |
| } |
| data2JsonReader := bytes.NewReader(data2Json) |
| req, err = http.NewRequest(method, path, data2JsonReader) |
| if err != nil { |
| t.Fatalf("http.NewRequest(%v, %v, %v,) failed: %v", method, path, data2JsonReader, err) |
| } |
| |
| resp2 := httptest.NewRecorder() |
| wspr.handleCreateAccount(resp2, req) |
| if resp2.Code != 200 { |
| t.Fatalf("Expected handleCreateAccount to return 200 OK, instead got %v", resp2) |
| } |
| |
| // Verify that idManager has both accounts |
| gotAccounts = wspr.idManager.AccountsMatching(security.BlessingPattern(fmt.Sprintf("%s%s%v", topLevelName, security.ChainSeparator, security.AllPrincipals))) |
| if len(gotAccounts) != 2 { |
| t.Fatalf("Expected to have 2 accounts, but got %v: %v", len(gotAccounts), gotAccounts) |
| } |
| } |
| |
| func TestHandleAssocAccount(t *testing.T) { |
| wspr, teardown := setup(t) |
| defer teardown() |
| |
| // First create an accounts. |
| accountName := "mock-account" |
| identityName := "mock-id" |
| privateID, err := wspr.rt.NewIdentity(identityName) |
| if err != nil { |
| t.Fatalf("wspr.rt.NewIdentity(%v) failed: %v", identityName, err) |
| } |
| if err := wspr.idManager.AddAccount(accountName, privateID); err != nil { |
| t.Fatalf("wspr.idManager.AddAccount(%v, %v) failed; %v", accountName, privateID, err) |
| } |
| |
| // Associate with that account |
| method := "POST" |
| path := "/assoc-account" |
| |
| origin := "https://my.webapp.com:443" |
| data := assocAccountInput{ |
| Name: accountName, |
| Origin: origin, |
| } |
| |
| dataJson, err := json.Marshal(data) |
| if err != nil { |
| t.Fatalf("json.Marshal(%v) failed: %v", data, err) |
| } |
| |
| dataJsonReader := bytes.NewReader(dataJson) |
| req, err := http.NewRequest(method, path, (dataJsonReader)) |
| if err != nil { |
| t.Fatalf("http.NewRequest(%v, %v, %v,) failed: %v", method, path, dataJsonReader, err) |
| } |
| |
| resp := httptest.NewRecorder() |
| wspr.handleAssocAccount(resp, req) |
| if resp.Code != 200 { |
| t.Fatalf("Expected handleAssocAccount to return 200 OK, instead got %v", resp) |
| } |
| |
| // Verify that idManager has the correct identity for the origin |
| gotID, err := wspr.idManager.Identity(origin) |
| if err != nil { |
| t.Fatalf("wspr.idManager.Identity(%v) failed: %v", origin, err) |
| } |
| |
| if gotID == nil { |
| t.Fatalf("Expected wspr.idManager.Identity(%v) to return an valid identity, but got %v", origin, gotID) |
| } |
| } |
| |
| func TestHandleAssocAccountWithMissingAccount(t *testing.T) { |
| wspr, teardown := setup(t) |
| defer teardown() |
| |
| method := "POST" |
| path := "/assoc-account" |
| |
| accountName := "mock-account" |
| origin := "https://my.webapp.com:443" |
| data := assocAccountInput{ |
| Name: accountName, |
| Origin: origin, |
| } |
| |
| dataJson, err := json.Marshal(data) |
| if err != nil { |
| t.Fatalf("json.Marshal(%v) failed: %v", data, err) |
| } |
| |
| dataJsonReader := bytes.NewReader(dataJson) |
| req, err := http.NewRequest(method, path, (dataJsonReader)) |
| if err != nil { |
| t.Fatalf("http.NewRequest(%v, %v, %v,) failed: %v", method, path, dataJsonReader, err) |
| } |
| |
| // Verify that the request fails with 400 Bad Request error |
| resp := httptest.NewRecorder() |
| wspr.handleAssocAccount(resp, req) |
| if resp.Code != 400 { |
| t.Fatalf("Expected handleAssocAccount to return 400 error, but got %v", resp) |
| } |
| |
| // Verify that idManager has no identities for the origin |
| gotID, err := wspr.idManager.Identity(origin) |
| if err == nil { |
| t.Fatalf("Expected wspr.idManager.Identity(%v) to fail, but got: %v", origin, gotID) |
| } |
| |
| if gotID != nil { |
| t.Fatalf("Expected wspr.idManager.Identity(%v) not to return an identity, but got %v", origin, gotID) |
| } |
| } |