// TestPostLogin verifies that /api/login returns proper JSON output func TestPostLogin(t *testing.T) { log.Println("TestPostLogin()") // Load config config, err := common.LoadConfig() if err != nil { t.Fatalf("Could not load configuration: %s", err.Error()) } common.Static.Config = config // Generate mock data.UserRecord mockUser := new(data.UserRecord) if err := mockUser.Create("test", "test", 100); err != nil { t.Fatalf("Failed to create mock user: %s", err.Error()) } // Save mock user if err := mockUser.Save(); err != nil { t.Fatalf("Failed to save mock user: %s", err.Error()) } // Load mock user to fetch ID user, err := mockUser.Load(mockUser.Username, "username") if user == (data.UserRecord{}) || err != nil { t.Fatalf("Failed to load mock user: %s", err.Error()) } // Perform login request for this user res, err := postLogin(user) if err != nil { t.Fatalf("Failed to retrieve login JSON: %s", err.Error()) } log.Println(string(res)) // Unmarshal output JSON var key data.JSONAPIKey err = json.Unmarshal(res, &key) if err != nil { t.Fatalf("Failed to unmarshal login JSON: %s", err.Error()) } // Verify same user ID from API if user.ID != key.UserID { t.Fatalf("Mismatched user IDs, got %d, expected %d", key.UserID, user.ID) } // Delete mock user if err := user.Delete(); err != nil { t.Fatalf("Failed to delete mock user: %s", err.Error()) } }
// TestBasicAuthenticator verifies that BasicAuthenticator.Auth works properly func TestBasicAuthenticator(t *testing.T) { log.Println("TestBasicAuthenticator()") // Load config config := common.LoadConfig() common.Static.Config = config // Generate mock user user := data.UserRecord{ Username: "******", Passkey: "abcdef0123456789", TorrentLimit: 10, } // Save mock user if !user.Save() { t.Fatalf("Failed to save mock user") } // Load mock user to fetch ID user = user.Load(user.Username, "username") if user == (data.UserRecord{}) { t.Fatalf("Failed to load mock user") } // Generate an API key and salt pass := "******" salt := "test" sha := sha1.New() sha.Write([]byte(pass + salt)) hash := fmt.Sprintf("%x", sha.Sum(nil)) // Generate mock API key key := data.APIKey{ UserID: user.ID, Key: hash, Salt: salt, } // Save mock API key if !key.Save() { t.Fatalf("Failed to save mock data.APIKey") } // Load mock data.APIKey to fetch ID key = key.Load(key.Key, "key") if key == (data.APIKey{}) { t.Fatalf("Failed to load mock data.APIKey") } // Generate mock HTTP request r := http.Request{} headers := map[string][]string{ "Authorization": {"Basic " + base64.URLEncoding.EncodeToString([]byte(user.Username+":"+pass))}, } r.Header = headers // Perform authentication request auth := new(BasicAuthenticator).Auth(&r) if !auth { t.Fatalf("Failed to authenticate using BasicAuthenticator") } // Delete mock user if !user.Delete() { t.Fatalf("Failed to delete mock user") } // Delete mock API key if !key.Delete() { t.Fatalf("Failed to delete mock data.APIKey") } }
// TestGetUsersJSON verifies that /api/users returns proper JSON output func TestGetUsersJSON(t *testing.T) { log.Println("TestGetUsersJSON()") // Load config config, err := common.LoadConfig() if err != nil { t.Fatalf("Could not load configuration: %s", err.Error()) } common.Static.Config = config // Generate mock data.UserRecord mockUser := new(data.UserRecord) if err := mockUser.Create("test", "test", 100); err != nil { t.Fatalf("Failed to create mock user: %s", err.Error()) } // Save mock user if err := mockUser.Save(); err != nil { t.Fatalf("Failed to save mock user: %s", err.Error()) } // Load mock user to fetch ID user, err := mockUser.Load(mockUser.Username, "username") if user == (data.UserRecord{}) || err != nil { t.Fatalf("Failed to load mock user: %s", err.Error()) } // Request output JSON from API for this user res, err := getUsersJSON(user.ID) if err != nil { t.Fatalf("Failed to retrieve users JSON: %s", err.Error()) } // Unmarshal output JSON var user2 data.UserRecord err = json.Unmarshal(res, &user2) if err != nil { t.Fatalf("Failed to unmarshal result JSON for single user: %s", err.Error()) } // Verify objects are the same if user.ID != user2.ID { t.Fatalf("ID, expected %d, got %d", user.ID, user2.ID) } // Request output JSON from API for all users res, err = getUsersJSON(-1) if err != nil { t.Fatalf("Failed to retrieve all users JSON: %s", err.Error()) } // Unmarshal all output JSON var allUsers []data.JSONUserRecord err = json.Unmarshal(res, &allUsers) if err != nil { t.Fatalf("Failed to unmarshal result JSON for all users: %s", err.Error()) } // Verify known user is in result set found := false for _, f := range allUsers { if f.ID == user.ID { found = true } } if !found { t.Fatalf("Expected user not found in all users result set") } // Delete mock user if err := user.Delete(); err != nil { t.Fatalf("Failed to delete mock user: %s", err.Error()) } }
// TestAuthenticator verifies that the Basic and HMAC authenticators work properly func TestAuthenticator(t *testing.T) { log.Println("TestBasicAuthenticator()") // Load config config, err := common.LoadConfig() if err != nil { t.Fatalf("Could not load configuration: %s", err.Error()) } common.Static.Config = config // Generate mock user user := new(data.UserRecord) if err := user.Create("test", "test", 10); err != nil { t.Fatalf("Failed to create mock user: %s", err.Error()) } // Save mock user if err := user.Save(); err != nil { t.Fatalf("Failed to save mock user: %s", err.Error()) } // Load user to get ID user2, err := user.Load("test", "username") if err != nil || (user2 == data.UserRecord{}) { t.Fatalf("Failed to load mock user: %s", err.Error()) } // Generate mock HTTP request r, err := http.NewRequest("POST", "http://localhost:8080/api/login", nil) if err != nil { t.Fatalf("Failed to generate HTTP request: %s", err.Error()) } headers := map[string][]string{ "Authorization": {"Basic " + base64.URLEncoding.EncodeToString([]byte("test:test"))}, } r.Header = headers // Capture HTTP response with recorder w := httptest.NewRecorder() // Perform HTTP Basic authentication var apiAuth APIAuthenticator apiAuth = new(BasicAuthenticator) // Attempt Basic authentication clientErr, serverErr := apiAuth.Auth(r) if clientErr != nil { t.Fatalf("Failed to authenticate: client: %s", clientErr.Error()) } if serverErr != nil { t.Fatalf("Failed to authenticate: server: %s", serverErr.Error()) } // Invoke API router Router(w, r, user2) // Read HTTP response body body, err := ioutil.ReadAll(w.Body) if err != nil { t.Fatalf("Failed to read HTTP response body: %s", err.Error()) } // Unmarshal result JSON var login data.JSONAPIKey if err := json.Unmarshal(body, &login); err != nil { t.Fatalf("Failed to unmarshal login JSON: %s", err.Error()) } // Generate API signature nonce := "abcdef" method := "GET" resource := "/api/status" signature, err := apiSignature(login.UserID, nonce, method, resource, login.Secret) if err != nil { t.Fatalf("Failed to generate API signature: %s", err.Error()) } log.Println("signature:", signature) // Generate mock HTTP request r, err = http.NewRequest(method, "http://localhost:8080"+resource, nil) if err != nil { t.Fatalf("Failed to generate HTTP request: %s", err.Error()) } headers = map[string][]string{ "Authorization": {"Basic " + base64.URLEncoding.EncodeToString([]byte(login.Pubkey+":"+nonce+"/"+signature))}, } r.Header = headers // Capture HTTP response with recorder w = httptest.NewRecorder() // Attempt HMAC authentication apiAuth = new(HMACAuthenticator) clientErr, serverErr = apiAuth.Auth(r) if clientErr != nil { t.Fatalf("Failed to authenticate: client: %s", clientErr.Error()) } if serverErr != nil { t.Fatalf("Failed to authenticate: server: %s", serverErr.Error()) } // Invoke API router Router(w, r, user2) // Read HTTP response body body, err = ioutil.ReadAll(w.Body) if err != nil { t.Fatalf("Failed to read HTTP response body: %s", err.Error()) } log.Println(string(body)) // Delete mock user if err := user2.Delete(); err != nil { t.Fatalf("Failed to delete mock user: %s", err.Error()) } }