// postUsersJSON creates a user from a JSON body, returning a client string/server error pair func postUsersJSON(body []byte) (string, error) { // Unmarshal JSON from body var jsonUser data.UserRecord if err := json.Unmarshal(body, &jsonUser); err != nil { return "Malformed request JSON", nil } // Check for valid input if jsonUser.Username == "" || jsonUser.Password == "" || jsonUser.TorrentLimit == 0 { return "Missing required parameters: username, password, torrentLimit", nil } // Create user from input user := new(data.UserRecord) if err := user.Create(jsonUser.Username, jsonUser.Password, jsonUser.TorrentLimit); err != nil { return "", err } // Save user to database if err := user.Save(); err != nil { return "", err } return "", nil }
// 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()) } }
// 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()) } }