diff --git a/server/app/interactors/workspaces/update.rb b/server/app/interactors/workspaces/update.rb index f92807205..c92dd3b64 100644 --- a/server/app/interactors/workspaces/update.rb +++ b/server/app/interactors/workspaces/update.rb @@ -7,9 +7,11 @@ class Update include Interactor def call - workspace = Workspace.find_by(id: context.id) + workspace = context.user.workspaces.find_by(id: context.id) + return context.fail!(workspace:) if workspace.blank? + workspace.slug = "default" if workspace.slug.empty? - if workspace&.update(context.workspace_params) + if workspace.update(context.workspace_params) context.workspace = workspace else context.fail!(workspace:) diff --git a/server/spec/interactors/workspaces/update_spec.rb b/server/spec/interactors/workspaces/update_spec.rb index 1050e3717..3b7d3ea07 100644 --- a/server/spec/interactors/workspaces/update_spec.rb +++ b/server/spec/interactors/workspaces/update_spec.rb @@ -11,6 +11,10 @@ let(:context) { Workspaces::Update.call(id: workspace.id, user:, workspace_params: { name: new_name }) } describe ".call" do + before do + create(:workspace_user, workspace:, user:, role: create(:role, :admin)) + end + context "when the update is successful" do it "succeeds" do expect(context).to be_a_success @@ -41,5 +45,17 @@ expect(context.workspace.name).to eq(new_name) end end + + context "when workspace belongs to another user (IDOR)" do + let(:other_user) { create(:user) } + + it "fails and does not update the workspace" do + original_name = workspace.name + result = Workspaces::Update.call(id: workspace.id, user: other_user, workspace_params: { name: "Hacked" }) + + expect(result).to be_a_failure + expect(workspace.reload.name).to eq(original_name) + end + end end end