@@ -291,5 +291,90 @@ def test_create_empty_plugin_user_without_full_name(self):
291291 # Should use username as author
292292 self .assertEqual (plugin .author , "noname" )
293293
294+ @patch ("plugins.views.plugin_notify" , new = do_nothing )
295+ @patch ("plugins.tasks.generate_plugins_xml" , new = do_nothing )
296+ @patch ("plugins.validator._check_url_link" , new = do_nothing )
297+ @patch ("plugins.security_utils.run_security_scan" , new = do_nothing )
298+ def test_version_create_not_auto_approved_for_untrusted_user_on_approved_plugin (self ):
299+ """
300+ Security: uploading a new version via the web form must NOT be auto-approved
301+ because the plugin already has an approved version. Only the user's
302+ can_approve permission should grant approval.
303+ """
304+ self .client .login (username = "testuser" , password = "testpassword" )
305+
306+ # Create empty plugin then upload first version
307+ create_data = {"package_name" : "test_modul" , "name" : "Test Module Plugin" }
308+ self .client .post (self .url , create_data )
309+ plugin = Plugin .objects .get (package_name = "test_modul" )
310+
311+ valid_plugin = os .path .join (TESTFILE_DIR , "valid_plugin.zip_" )
312+ with open (valid_plugin , "rb" ) as file :
313+ uploaded_file = SimpleUploadedFile (
314+ "valid_plugin.zip_" , file .read (), content_type = "application/zip"
315+ )
316+ upload_url = reverse ("version_create" , args = [plugin .package_name ])
317+ self .client .post (upload_url , {"package" : uploaded_file })
318+
319+ # Simulate staff approval of the first version
320+ first_version = plugin .pluginversion_set .get (version = "0.0.1" )
321+ first_version .approved = True
322+ first_version .save ()
323+
324+ # Upload a second version as the same untrusted user
325+ valid_plugin_v2 = os .path .join (TESTFILE_DIR , "valid_plugin_0.0.2.zip_" )
326+ with open (valid_plugin_v2 , "rb" ) as file :
327+ uploaded_file_v2 = SimpleUploadedFile (
328+ "valid_plugin_0.0.2.zip_" , file .read (), content_type = "application/zip"
329+ )
330+ self .client .post (upload_url , {"package" : uploaded_file_v2 })
331+
332+ second_version = plugin .pluginversion_set .get (version = "0.0.2" )
333+ self .assertFalse (
334+ second_version .approved ,
335+ "New version must NOT be auto-approved just because the plugin is approved; "
336+ "only user trust (can_approve) should grant approval." ,
337+ )
338+
339+ @patch ("plugins.views.plugin_notify" , new = do_nothing )
340+ @patch ("plugins.tasks.generate_plugins_xml" , new = do_nothing )
341+ @patch ("plugins.validator._check_url_link" , new = do_nothing )
342+ @patch ("plugins.security_utils.run_security_scan" , new = do_nothing )
343+ def test_version_create_auto_approved_for_trusted_user (self ):
344+ """
345+ A user with can_approve permission should have their uploaded version
346+ approved automatically via the version_create view.
347+ """
348+ from django .contrib .auth .models import Permission
349+ from django .contrib .contenttypes .models import ContentType
350+ from plugins .models import Plugin as PluginModel
351+
352+ ct = ContentType .objects .get_for_model (PluginModel )
353+ perm = Permission .objects .get (codename = "can_approve" , content_type = ct )
354+ self .user .user_permissions .add (perm )
355+ # Refresh to bust Django's permission cache
356+ self .user = self .user .__class__ .objects .get (pk = self .user .pk )
357+
358+ self .client .login (username = "testuser" , password = "testpassword" )
359+
360+ # Create empty plugin then upload first version
361+ create_data = {"package_name" : "test_modul" , "name" : "Test Module Plugin" }
362+ self .client .post (self .url , create_data )
363+ plugin = Plugin .objects .get (package_name = "test_modul" )
364+
365+ valid_plugin = os .path .join (TESTFILE_DIR , "valid_plugin.zip_" )
366+ with open (valid_plugin , "rb" ) as file :
367+ uploaded_file = SimpleUploadedFile (
368+ "valid_plugin.zip_" , file .read (), content_type = "application/zip"
369+ )
370+ upload_url = reverse ("version_create" , args = [plugin .package_name ])
371+ self .client .post (upload_url , {"package" : uploaded_file })
372+
373+ version = plugin .pluginversion_set .get (version = "0.0.1" )
374+ self .assertTrue (
375+ version .approved ,
376+ "Version uploaded by a trusted user (can_approve) should be approved automatically." ,
377+ )
378+
294379 def tearDown (self ):
295380 self .client .logout ()
0 commit comments