diff --git a/lib/extends/permissions/initiatives/permissions_extends.rb b/lib/extends/permissions/initiatives/permissions_extends.rb index b0883406d2..30c94b4527 100644 --- a/lib/extends/permissions/initiatives/permissions_extends.rb +++ b/lib/extends/permissions/initiatives/permissions_extends.rb @@ -7,12 +7,17 @@ module PermissionsExtends def creation_enabled? return false unless Decidim::Initiatives.creation_enabled return true if no_authorizations_available? + return true if no_create_permission_on_initiative_type? user_can_create? && authorized?(:create, permissions_holder: initiative_type) end private + def no_create_permission_on_initiative_type? + initiative_type.permissions.nil? || initiative_type.permissions.keys.empty? || !initiative_type.permissions&.keys&.include?("create") + end + def no_authorizations_available? user&.organization&.available_authorizations&.empty? end diff --git a/spec/permissions/decidim/initiatives/permissions_spec.rb b/spec/permissions/decidim/initiatives/permissions_spec.rb index d347598104..3c2a26620c 100644 --- a/spec/permissions/decidim/initiatives/permissions_spec.rb +++ b/spec/permissions/decidim/initiatives/permissions_spec.rb @@ -206,90 +206,28 @@ end context "when creation is enabled" do - # Explicitly set available_authorizations to ensure the organization HAS authorizations configured - # This tests the standard behavior where users must be verified when authorizations exist - let(:organization) { create(:organization, available_authorizations: %w(dummy_authorization_handler)) } - before do allow(Decidim::Initiatives) .to receive(:creation_enabled) .and_return(true) end - it { is_expected.to be false } - - context "when authorizations are not required" do - before do - allow(Decidim::Initiatives) - .to receive(:do_not_require_authorization) - .and_return(true) - end - - it { is_expected.to be true } - end - - context "when user is authorized" do - before do - create(:authorization, :granted, user:) - end - - it { is_expected.to be true } - end - - context "when user belongs to a verified user group" do - before do - create(:user_group, :verified, users: [user], organization: user.organization) - end - - it { is_expected.to be true } - end - - context "when the initiative type has permissions to create" do - before do - initiative.type.create_resource_permission( - permissions: { - "create" => { - "authorization_handlers" => { - "dummy_authorization_handler" => { "options" => {} }, - "another_dummy_authorization_handler" => { "options" => {} } - } - } - } - ) - end - - # User lacks required authorizations AND organization has authorizations configured - # Standard behavior: creation should be denied - context "when user is not verified" do - it { is_expected.to be false } - end - - context "when user is fully verified" do - before do - create(:authorization, name: "dummy_authorization_handler", user:, granted_at: 2.seconds.ago) - create(:authorization, name: "another_dummy_authorization_handler", user:, granted_at: 2.seconds.ago) - end - - it { is_expected.to be true } - end - end - # When the org has NO authorizations configured, # creation should be allowed regardless of user verification status # This bypasses all authorization checks when available_authorizations is empty - context "when organization has no available authorizations" do + context "and there is no authorizations on organization" do let(:organization) { create(:organization, available_authorizations: []) } # Base case: unverified user with no authorizations required # Extension allows this because no_authorizations_available is true - context "when user is not verified" do + context "and user is not verified" do it "allows creation because no authorizations are configured" do expect(subject).to be true end end - # Verified user with no authorizations required - should still work - context "when user is verified" do + # Verified user - should still work + context "and user is verified" do before do create(:authorization, :granted, user:) end @@ -299,8 +237,19 @@ end end + # User belongs to a verified group - should still work + context "and user belongs to a verified user group" do + before do + create(:user_group, :verified, users: [user], organization: user.organization) + end + + it "allows creation" do + expect(subject).to be true + end + end + # Ensure do_not_require_authorization flag still works with no authorizations available - context "when authorizations are not required" do + context "and authorizations are not required" do before do allow(Decidim::Initiatives) .to receive(:do_not_require_authorization) @@ -315,7 +264,7 @@ # CRITICAL TEST: Initiative type requires specific authorization BUT organization has none configured # Extend should bypass the initiative type's authorization requirements # because no_authorizations_available takes precedence - context "when the initiative type has permissions to create" do + context "and the initiative type has permission on create" do before do initiative.type.create_resource_permission( permissions: { @@ -330,15 +279,105 @@ # KEY BEHAVIOR: Even though initiative type requires dummy_authorization_handler, # creation is allowed because the organization has no authorizations configured - context "when user is not verified" do + context "and user is not verified" do it "allows creation because no authorizations are available in the organization" do expect(subject).to be true end end # Verified user should also be allowed - context "when user is verified" do + context "and user is verified" do + before do + create(:authorization, name: "dummy_authorization_handler", user:, granted_at: 2.seconds.ago) + end + + it "allows creation" do + expect(subject).to be true + end + end + end + end + + # When the org HAS authorization configured, but there is NO permission on initiative_type + # creation should be allowed regardless of user verification status + context "and there is authorization on organization" do + # Explicitly set available_authorizations to ensure the organization HAS authorizations configured + let(:organization) { create(:organization, available_authorizations: %w(dummy_authorization_handler)) } + + # NO permission on initiative_type + # Extension allows this because no_create_permission_on_initiative_type? will be true + context "and there is no permission on initiative_type" do + it { is_expected.to be true } + end + + # Permission on initiative_type on vote but NOT on create + # Extension allows this because no_create_permission_on_initiative_type? will be true + context "and there is a permission on vote on initiative_type" do + before do + initiative.type.create_resource_permission( + permissions: { + "vote" => { + "authorization_handlers" => { + "dummy_authorization_handler" => { "options" => {} }, + "another_dummy_authorization_handler" => { "options" => {} } + } + } + } + ) + end + + it { is_expected.to be true } + end + + # This tests the behavior where users must be verified when authorizations exist on organization + # and there are permissions on create on initiative_type + context "and there are permissions on create on initiative_type" do + before do + initiative.type.create_resource_permission( + permissions: { + "create" => { + "authorization_handlers" => { + "dummy_authorization_handler" => { "options" => {} }, + "another_dummy_authorization_handler" => { "options" => {} } + } + } + } + ) + end + + # Unverified user should not be allowed + context "and user is not verified" do + it "doesn't allow creation" do + expect(subject).to be false + end + end + + # User belonging to a verified group but not authorized should not be allowed + context "and user belongs to a verified user group but is not authorized" do + before do + create(:user_group, :verified, users: [user], organization: user.organization) + end + + it "does not allow creation" do + expect(subject).to be false + end + end + + # Verified user should be allowed + context "and user is verified" do + before do + create(:authorization, name: "dummy_authorization_handler", user:, granted_at: 2.seconds.ago) + end + + it "allows creation" do + expect(subject).to be true + end + end + + # User belonging to a verified group and authorized should be allowed + context "and user belongs to a verified user group and is authorized" do before do + create(:user_group, :verified, users: [user], organization: user.organization) create(:authorization, name: "dummy_authorization_handler", user:, granted_at: 2.seconds.ago) end