@@ -667,15 +667,11 @@ def test_user_can_be_assigned_to_multiple_wireguard_interfaces(access_token):
667667 # Get the auto-allocated peer IPs
668668 peer_ips = user ["proxy_settings" ]["wireguard" ]["peer_ips" ]
669669
670- # Verify that peer_ips is a non- empty list (auto-allocated from global pool )
670+ # peer_ips should be empty in user settings (dynamically generated during subscription )
671671 assert isinstance (peer_ips , list )
672- assert len (peer_ips ) > 0
672+ assert len (peer_ips ) == 0
673673
674- # All peer IPs should be /32 (single hosts)
675- for peer_ip in peer_ips :
676- assert peer_ip .endswith ("/32" )
677-
678- # Verify that the same peer_ips are used for all WireGuard interfaces
674+ # Verify that peer IPs are dynamically generated during subscription
679675 links_response = client .get (f"{ user ['subscription_url' ]} /links" )
680676 assert links_response .status_code == status .HTTP_200_OK
681677
@@ -686,37 +682,48 @@ def test_user_can_be_assigned_to_multiple_wireguard_interfaces(access_token):
686682 parsed = urlsplit (line .strip ())
687683 links_by_endpoint [f"{ parsed .hostname } :{ parsed .port } " ] = parse_qs (parsed .query )
688684
689- # Both endpoints should have the same peer IPs
690- expected_address = "," .join (peer_ips )
691- assert links_by_endpoint [f"{ first_endpoint } :51820" ]["address" ] == [expected_address ]
692- assert links_by_endpoint [f"{ second_endpoint } :51821" ]["address" ] == [expected_address ]
685+ # Both endpoints should have peer IPs generated from interface addresses
686+ # User ID 17 with first_interface address "10.30.10.1/24" should get "10.30.10.18/32"
687+ # User ID 17 with second_interface address "10.40.10.1/24" should get "10.40.10.18/32"
688+ first_address = links_by_endpoint [f"{ first_endpoint } :51820" ]["address" ][0 ]
689+ second_address = links_by_endpoint [f"{ second_endpoint } :51821" ]["address" ][0 ]
690+
691+ # Verify IPs are from correct ranges
692+ assert first_address .startswith ("10.30.10." )
693+ assert second_address .startswith ("10.40.10." )
694+ assert first_address .endswith ("/32" )
695+ assert second_address .endswith ("/32" )
693696
694697 # Verify WireGuard subscription contains the peer IPs
695698 wireguard_response = client .get (f"{ user ['subscription_url' ]} /wireguard" )
696699 assert wireguard_response .status_code == status .HTTP_200_OK
697700 config_bodies = extract_wireguard_config_bodies (wireguard_response )
698701 assert len (config_bodies ) == 2
699702
700- expected_address = f"Address = { ', ' .join (peer_ips )} "
703+ # Verify each config has correct Address from respective interface
704+ for body in config_bodies :
705+ # Should have Address from one of the interfaces
706+ assert "Address = 10.30.10." in body or "Address = 10.40.10." in body
707+ assert "/32" in body
708+
701709 expected_endpoints = {f"Endpoint = { first_endpoint } :51820" , f"Endpoint = { second_endpoint } :51821" }
702710 actual_endpoints = set ()
703711
704712 for body in config_bodies :
705- assert expected_address in body
706713 for endpoint in expected_endpoints :
707714 if endpoint in body :
708715 actual_endpoints .add (endpoint )
709716
710717 assert actual_endpoints == expected_endpoints
711718
712- # Test no-op update preserves peer_ips
719+ # Test no-op update preserves empty peer_ips
713720 update_response = client .put (
714721 f"/api/user/{ user ['username' ]} " ,
715722 headers = auth_headers (access_token ),
716723 json = {"note" : "keep existing wireguard allocations" },
717724 )
718725 assert update_response .status_code == status .HTTP_200_OK
719- assert update_response .json ()["proxy_settings" ]["wireguard" ]["peer_ips" ] == peer_ips
726+ assert update_response .json ()["proxy_settings" ]["wireguard" ]["peer_ips" ] == []
720727 finally :
721728 delete_user (access_token , user ["username" ])
722729 delete_group (access_token , group ["id" ])
@@ -1579,16 +1586,29 @@ def test_wireguard_peer_ip_global_pool_and_validation(access_token):
15791586 assert response .status_code == status .HTTP_400_BAD_REQUEST
15801587 assert "reserved for the server" in response .json ()["detail" ]
15811588
1582- # Test 2: Create user without specifying peer IPs - should get IP from global pool
1589+ # Test 2: Create user without specifying peer IPs - should get IP dynamically during subscription
15831590 user1 = create_user (
15841591 access_token ,
15851592 group_ids = [group ["id" ]],
15861593 payload = {"username" : unique_name ("wg_auto_ip_user1" )},
15871594 )
1588- assert user1 ["proxy_settings" ]["wireguard" ]["peer_ips" ]
1589- peer_ip1 = user1 ["proxy_settings" ]["wireguard" ]["peer_ips" ][0 ]
1595+ # peer_ips should be empty in user settings
1596+ assert user1 ["proxy_settings" ]["wireguard" ]["peer_ips" ] == []
1597+
1598+ # But subscription should work with dynamically allocated IP from global pool
1599+ links_response = client .get (f"{ user1 ['subscription_url' ]} /links" )
1600+ assert links_response .status_code == status .HTTP_200_OK
1601+
1602+ # Should have a wireguard link with an IP from global pool (10.0.0.0/8)
1603+ link = links_response .text .strip ()
1604+ assert link .startswith ("wireguard://" )
1605+ parsed = urlsplit (link )
1606+ query = parse_qs (parsed .query )
1607+ peer_ip1 = query .get ("address" , ["" ])[0 ]
1608+ # Should be an IP from 10.0.0.0/8 pool
15901609 assert peer_ip1 .startswith ("10." )
1591- assert peer_ip1 != "10.0.0.1/32"
1610+ assert peer_ip1 .endswith ("/32" )
1611+ assert peer_ip1 != "10.0.0.1/32" # Should not be the reserved server IP
15921612
15931613 # Test 3: Try to create another user with the same IP - should fail
15941614 response = client .post (
@@ -1604,29 +1624,31 @@ def test_wireguard_peer_ip_global_pool_and_validation(access_token):
16041624 "group_ids" : [group ["id" ]],
16051625 },
16061626 )
1627+ # Since peer_ips are dynamically generated, manually specifying a duplicate should be rejected
16071628 assert response .status_code == status .HTTP_400_BAD_REQUEST
16081629 assert "already in use" in response .json ()["detail" ]
16091630
1610- # Test 4: Create another user without specifying peer IPs - should get different IP
1631+ # Test 4: Create another user without specifying peer IPs - should get different IP dynamically
16111632 user2 = create_user (
16121633 access_token ,
16131634 group_ids = [group ["id" ]],
16141635 payload = {"username" : unique_name ("wg_auto_ip_user2" )},
16151636 )
1616- assert user2 ["proxy_settings" ]["wireguard" ]["peer_ips" ]
1617- peer_ip2 = user2 ["proxy_settings" ]["wireguard" ]["peer_ips" ][0 ]
1637+ # peer_ips should be empty in user settings
1638+ assert user2 ["proxy_settings" ]["wireguard" ]["peer_ips" ] == []
1639+
1640+ # Get dynamically allocated IP from subscription
1641+ links_response2 = client .get (f"{ user2 ['subscription_url' ]} /links" )
1642+ assert links_response2 .status_code == status .HTTP_200_OK
1643+ link2 = links_response2 .text .strip ()
1644+ assert link2 .startswith ("wireguard://" )
1645+ parsed2 = urlsplit (link2 )
1646+ query2 = parse_qs (parsed2 .query )
1647+ peer_ip2 = query2 .get ("address" , ["" ])[0 ]
16181648 assert peer_ip2 .startswith ("10." )
1649+ assert peer_ip2 .endswith ("/32" )
1650+ # Different users should get different IPs
16191651 assert peer_ip2 != peer_ip1
1620- assert peer_ip2 != "10.0.0.1/32"
1621-
1622- # Test 5: Verify subscription links work with auto-allocated IPs
1623- links_response = client .get (f"{ user1 ['subscription_url' ]} /links" )
1624- assert links_response .status_code == status .HTTP_200_OK
1625- link = links_response .text .strip ()
1626- assert link .startswith ("wireguard://" )
1627- parsed = urlsplit (link )
1628- query = parse_qs (parsed .query )
1629- assert query ["address" ] == [peer_ip1 ]
16301652
16311653 finally :
16321654 if user1 :
0 commit comments