1# frozen_string_literal: true 2 3require 'spec_helper' 4 5RSpec.describe ProjectPolicy do 6 include ExternalAuthorizationServiceHelpers 7 include AdminModeHelper 8 include_context 'ProjectPolicy context' 9 10 let(:project) { public_project } 11 12 subject { described_class.new(current_user, project) } 13 14 def expect_allowed(*permissions) 15 permissions.each { |p| is_expected.to be_allowed(p) } 16 end 17 18 def expect_disallowed(*permissions) 19 permissions.each { |p| is_expected.not_to be_allowed(p) } 20 end 21 22 context 'with no project feature' do 23 let(:current_user) { owner } 24 25 before do 26 project.project_feature.destroy! 27 project.reload 28 end 29 30 it 'returns false' do 31 is_expected.to be_disallowed(:read_build) 32 end 33 end 34 35 it 'does not include the read_issue permission when the issue author is not a member of the private project' do 36 project = create(:project, :private) 37 issue = create(:issue, project: project, author: create(:user)) 38 user = issue.author 39 40 expect(project.team.member?(issue.author)).to be false 41 42 expect(Ability).not_to be_allowed(user, :read_issue, project) 43 end 44 45 it_behaves_like 'model with wiki policies' do 46 let(:container) { project } 47 let_it_be(:user) { owner } 48 49 def set_access_level(access_level) 50 project.project_feature.update_attribute(:wiki_access_level, access_level) 51 end 52 end 53 54 context 'issues feature' do 55 let(:current_user) { owner } 56 57 context 'when the feature is disabled' do 58 before do 59 project.issues_enabled = false 60 project.save! 61 end 62 63 it 'does not include the issues permissions' do 64 expect_disallowed :read_issue, :read_issue_iid, :create_issue, :update_issue, :admin_issue, :create_incident 65 end 66 67 it 'disables boards and lists permissions' do 68 expect_disallowed :read_issue_board, :create_board, :update_board 69 expect_disallowed :read_issue_board_list, :create_list, :update_list, :admin_issue_board_list 70 end 71 72 context 'when external tracker configured' do 73 it 'does not include the issues permissions' do 74 create(:jira_integration, project: project) 75 76 expect_disallowed :read_issue, :read_issue_iid, :create_issue, :update_issue, :admin_issue, :create_incident 77 end 78 end 79 end 80 end 81 82 context 'merge requests feature' do 83 let(:current_user) { owner } 84 85 it 'disallows all permissions when the feature is disabled' do 86 project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) 87 88 mr_permissions = [:create_merge_request_from, :read_merge_request, 89 :update_merge_request, :admin_merge_request, 90 :create_merge_request_in] 91 92 expect_disallowed(*mr_permissions) 93 end 94 end 95 96 context 'for a guest in a private project' do 97 let(:current_user) { guest } 98 let(:project) { private_project } 99 100 it 'disallows the guest from reading the merge request and merge request iid' do 101 expect_disallowed(:read_merge_request) 102 expect_disallowed(:read_merge_request_iid) 103 end 104 end 105 106 context 'pipeline feature' do 107 let(:project) { private_project } 108 let(:current_user) { developer } 109 let(:pipeline) { create(:ci_pipeline, project: project) } 110 111 describe 'for confirmed user' do 112 it 'allows modify pipelines' do 113 expect_allowed(:create_pipeline) 114 expect_allowed(:update_pipeline) 115 expect_allowed(:create_pipeline_schedule) 116 end 117 end 118 119 describe 'for unconfirmed user' do 120 let(:current_user) { project.owner.tap { |u| u.update!(confirmed_at: nil) } } 121 122 it 'disallows to modify pipelines' do 123 expect_disallowed(:create_pipeline) 124 expect_disallowed(:update_pipeline) 125 expect_disallowed(:destroy_pipeline) 126 expect_disallowed(:create_pipeline_schedule) 127 end 128 end 129 130 describe 'destroy permission' do 131 describe 'for developers' do 132 it 'prevents :destroy_pipeline' do 133 expect(current_user.can?(:destroy_pipeline, pipeline)).to be_falsey 134 end 135 end 136 137 describe 'for maintainers' do 138 let(:current_user) { maintainer } 139 140 it 'prevents :destroy_pipeline' do 141 project.add_maintainer(maintainer) 142 expect(current_user.can?(:destroy_pipeline, pipeline)).to be_falsey 143 end 144 end 145 146 describe 'for project owner' do 147 let(:current_user) { project.owner } 148 149 it 'allows :destroy_pipeline' do 150 expect(current_user.can?(:destroy_pipeline, pipeline)).to be_truthy 151 end 152 153 context 'on archived projects' do 154 before do 155 project.update!(archived: true) 156 end 157 158 it 'prevents :destroy_pipeline' do 159 expect(current_user.can?(:destroy_pipeline, pipeline)).to be_falsey 160 end 161 end 162 163 context 'on archived pending_delete projects' do 164 before do 165 project.update!(archived: true, pending_delete: true) 166 end 167 168 it 'allows :destroy_pipeline' do 169 expect(current_user.can?(:destroy_pipeline, pipeline)).to be_truthy 170 end 171 end 172 end 173 end 174 end 175 176 context 'builds feature' do 177 context 'when builds are disabled' do 178 let(:current_user) { owner } 179 180 before do 181 project.project_feature.update!(builds_access_level: ProjectFeature::DISABLED) 182 end 183 184 it 'disallows all permissions except pipeline when the feature is disabled' do 185 builds_permissions = [ 186 :create_build, :read_build, :update_build, :admin_build, :destroy_build, 187 :create_pipeline_schedule, :read_pipeline_schedule_variables, :update_pipeline_schedule, :admin_pipeline_schedule, :destroy_pipeline_schedule, 188 :create_environment, :read_environment, :update_environment, :admin_environment, :destroy_environment, 189 :create_cluster, :read_cluster, :update_cluster, :admin_cluster, :destroy_cluster, 190 :create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment 191 ] 192 193 expect_disallowed(*builds_permissions) 194 end 195 end 196 197 context 'when builds are disabled only for some users' do 198 let(:current_user) { guest } 199 200 before do 201 project.project_feature.update!(builds_access_level: ProjectFeature::PRIVATE) 202 end 203 204 it 'disallows pipeline and commit_status permissions' do 205 builds_permissions = [ 206 :create_pipeline, :update_pipeline, :admin_pipeline, :destroy_pipeline, 207 :create_commit_status, :update_commit_status, :admin_commit_status, :destroy_commit_status 208 ] 209 210 expect_disallowed(*builds_permissions) 211 end 212 end 213 end 214 215 context 'repository feature' do 216 let(:repository_permissions) do 217 [ 218 :create_pipeline, :update_pipeline, :admin_pipeline, :destroy_pipeline, 219 :create_build, :read_build, :update_build, :admin_build, :destroy_build, 220 :create_pipeline_schedule, :read_pipeline_schedule, :update_pipeline_schedule, :admin_pipeline_schedule, :destroy_pipeline_schedule, 221 :create_environment, :read_environment, :update_environment, :admin_environment, :destroy_environment, 222 :create_cluster, :read_cluster, :update_cluster, :admin_cluster, 223 :create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment, 224 :destroy_release, :download_code, :build_download_code 225 ] 226 end 227 228 context 'when user is a project member' do 229 let(:current_user) { owner } 230 231 context 'when it is disabled' do 232 before do 233 project.project_feature.update!( 234 repository_access_level: ProjectFeature::DISABLED, 235 merge_requests_access_level: ProjectFeature::DISABLED, 236 builds_access_level: ProjectFeature::DISABLED, 237 forking_access_level: ProjectFeature::DISABLED 238 ) 239 end 240 241 it 'disallows all permissions' do 242 expect_disallowed(*repository_permissions) 243 end 244 end 245 end 246 247 context 'when user is non-member' do 248 let(:current_user) { non_member } 249 250 context 'when access level is private' do 251 before do 252 project.project_feature.update!( 253 repository_access_level: ProjectFeature::PRIVATE, 254 merge_requests_access_level: ProjectFeature::PRIVATE, 255 builds_access_level: ProjectFeature::PRIVATE, 256 forking_access_level: ProjectFeature::PRIVATE 257 ) 258 end 259 260 it 'disallows all permissions' do 261 expect_disallowed(*repository_permissions) 262 end 263 end 264 end 265 end 266 267 it_behaves_like 'project policies as anonymous' 268 it_behaves_like 'project policies as guest' 269 it_behaves_like 'project policies as reporter' 270 it_behaves_like 'project policies as developer' 271 it_behaves_like 'project policies as maintainer' 272 it_behaves_like 'project policies as owner' 273 it_behaves_like 'project policies as admin with admin mode' 274 it_behaves_like 'project policies as admin without admin mode' 275 276 context 'when a public project has merge requests allowing access' do 277 include ProjectForksHelper 278 let(:current_user) { create(:user) } 279 let(:target_project) { create(:project, :public) } 280 let(:project) { fork_project(target_project) } 281 let!(:merge_request) do 282 create( 283 :merge_request, 284 target_project: target_project, 285 source_project: project, 286 allow_collaboration: true 287 ) 288 end 289 290 let(:maintainer_abilities) do 291 %w(create_build create_pipeline) 292 end 293 294 it 'does not allow pushing code' do 295 expect_disallowed(*maintainer_abilities) 296 end 297 298 it 'allows pushing if the user is a member with push access to the target project' do 299 target_project.add_developer(current_user) 300 301 expect_allowed(*maintainer_abilities) 302 end 303 304 it 'disallows abilities to a maintainer if the merge request was closed' do 305 target_project.add_developer(current_user) 306 merge_request.close! 307 308 expect_disallowed(*maintainer_abilities) 309 end 310 end 311 312 it_behaves_like 'clusterable policies' do 313 let_it_be(:clusterable) { create(:project, :repository) } 314 let_it_be(:cluster) do 315 create(:cluster, :provided_by_gcp, :project, projects: [clusterable]) 316 end 317 end 318 319 context 'reading a project' do 320 it 'allows access when a user has read access to the repo' do 321 expect(described_class.new(owner, project)).to be_allowed(:read_project) 322 expect(described_class.new(developer, project)).to be_allowed(:read_project) 323 expect(described_class.new(admin, project)).to be_allowed(:read_project) 324 end 325 326 it 'never checks the external service' do 327 expect(::Gitlab::ExternalAuthorization).not_to receive(:access_allowed?) 328 329 expect(described_class.new(owner, project)).to be_allowed(:read_project) 330 end 331 332 context 'with an external authorization service' do 333 before do 334 enable_external_authorization_service_check 335 end 336 337 it 'allows access when the external service allows it' do 338 external_service_allow_access(owner, project) 339 external_service_allow_access(developer, project) 340 341 expect(described_class.new(owner, project)).to be_allowed(:read_project) 342 expect(described_class.new(developer, project)).to be_allowed(:read_project) 343 end 344 345 context 'with an admin' do 346 context 'when admin mode is enabled', :enable_admin_mode do 347 it 'does not check the external service and allows access' do 348 expect(::Gitlab::ExternalAuthorization).not_to receive(:access_allowed?) 349 350 expect(described_class.new(admin, project)).to be_allowed(:read_project) 351 end 352 end 353 354 context 'when admin mode is disabled' do 355 it 'checks the external service and allows access' do 356 external_service_allow_access(admin, project) 357 358 expect(::Gitlab::ExternalAuthorization).to receive(:access_allowed?) 359 360 expect(described_class.new(admin, project)).to be_allowed(:read_project) 361 end 362 end 363 end 364 365 it 'prevents all but seeing a public project in a list when access is denied' do 366 [developer, owner, build(:user), nil].each do |user| 367 external_service_deny_access(user, project) 368 policy = described_class.new(user, project) 369 370 expect(policy).not_to be_allowed(:read_project) 371 expect(policy).not_to be_allowed(:owner_access) 372 expect(policy).not_to be_allowed(:change_namespace) 373 end 374 end 375 376 it 'passes the full path to external authorization for logging purposes' do 377 expect(::Gitlab::ExternalAuthorization) 378 .to receive(:access_allowed?).with(owner, 'default_label', project.full_path).and_call_original 379 380 described_class.new(owner, project).allowed?(:read_project) 381 end 382 end 383 end 384 385 context 'forking a project' do 386 context 'anonymous user' do 387 let(:current_user) { anonymous } 388 389 it { is_expected.to be_disallowed(:fork_project) } 390 end 391 392 context 'project member' do 393 let(:project) { private_project } 394 395 context 'guest' do 396 let(:current_user) { guest } 397 398 it { is_expected.to be_disallowed(:fork_project) } 399 end 400 401 %w(reporter developer maintainer).each do |role| 402 context role do 403 let(:current_user) { send(role) } 404 405 it { is_expected.to be_allowed(:fork_project) } 406 end 407 end 408 end 409 end 410 411 describe 'update_max_artifacts_size' do 412 context 'when no user' do 413 let(:current_user) { anonymous } 414 415 it { expect_disallowed(:update_max_artifacts_size) } 416 end 417 418 context 'admin' do 419 let(:current_user) { admin } 420 421 context 'when admin mode is enabled', :enable_admin_mode do 422 it { expect_allowed(:update_max_artifacts_size) } 423 end 424 425 context 'when admin mode is disabled' do 426 it { expect_disallowed(:update_max_artifacts_size) } 427 end 428 end 429 430 %w(guest reporter developer maintainer owner).each do |role| 431 context role do 432 let(:current_user) { send(role) } 433 434 it { expect_disallowed(:update_max_artifacts_size) } 435 end 436 end 437 end 438 439 describe 'read_storage_disk_path' do 440 context 'when no user' do 441 let(:current_user) { anonymous } 442 443 it { expect_disallowed(:read_storage_disk_path) } 444 end 445 446 context 'admin' do 447 let(:current_user) { admin } 448 449 context 'when admin mode is enabled', :enable_admin_mode do 450 it { expect_allowed(:read_storage_disk_path) } 451 end 452 453 context 'when admin mode is disabled' do 454 it { expect_disallowed(:read_storage_disk_path) } 455 end 456 end 457 458 %w(guest reporter developer maintainer owner).each do |role| 459 context role do 460 let(:current_user) { send(role) } 461 462 it { expect_disallowed(:read_storage_disk_path) } 463 end 464 end 465 end 466 467 context 'alert bot' do 468 let(:current_user) { User.alert_bot } 469 470 it { is_expected.to be_allowed(:reporter_access) } 471 472 context 'within a private project' do 473 let(:project) { private_project } 474 475 it { is_expected.to be_allowed(:admin_issue) } 476 end 477 end 478 479 describe 'set_pipeline_variables' do 480 context 'when user is developer' do 481 let(:current_user) { developer } 482 483 context 'when project allows user defined variables' do 484 before do 485 project.update!(restrict_user_defined_variables: false) 486 end 487 488 it { is_expected.to be_allowed(:set_pipeline_variables) } 489 end 490 491 context 'when project restricts use of user defined variables' do 492 before do 493 project.update!(restrict_user_defined_variables: true) 494 end 495 496 it { is_expected.not_to be_allowed(:set_pipeline_variables) } 497 end 498 end 499 500 context 'when user is maintainer' do 501 let(:current_user) { maintainer } 502 503 context 'when project allows user defined variables' do 504 before do 505 project.update!(restrict_user_defined_variables: false) 506 end 507 508 it { is_expected.to be_allowed(:set_pipeline_variables) } 509 end 510 511 context 'when project restricts use of user defined variables' do 512 before do 513 project.update!(restrict_user_defined_variables: true) 514 end 515 516 it { is_expected.to be_allowed(:set_pipeline_variables) } 517 end 518 end 519 end 520 521 context 'support bot' do 522 let(:current_user) { User.support_bot } 523 524 context 'with service desk disabled' do 525 it { expect_allowed(:public_access) } 526 it { expect_disallowed(:guest_access, :create_note, :read_project) } 527 end 528 529 context 'with service desk enabled' do 530 before do 531 allow(project).to receive(:service_desk_enabled?).and_return(true) 532 end 533 534 it { expect_allowed(:reporter_access, :create_note, :read_issue) } 535 536 context 'when issues are protected members only' do 537 before do 538 project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE) 539 end 540 541 it { expect_allowed(:reporter_access, :create_note, :read_issue) } 542 end 543 end 544 end 545 546 context "project bots" do 547 let(:project_bot) { create(:user, :project_bot) } 548 let(:user) { create(:user) } 549 550 context "project_bot_access" do 551 context "when regular user and part of the project" do 552 let(:current_user) { user } 553 554 before do 555 project.add_developer(user) 556 end 557 558 it { is_expected.not_to be_allowed(:project_bot_access)} 559 end 560 561 context "when project bot and not part of the project" do 562 let(:current_user) { project_bot } 563 564 it { is_expected.not_to be_allowed(:project_bot_access)} 565 end 566 567 context "when project bot and part of the project" do 568 let(:current_user) { project_bot } 569 570 before do 571 project.add_developer(project_bot) 572 end 573 574 it { is_expected.to be_allowed(:project_bot_access)} 575 end 576 end 577 578 context 'with resource access tokens' do 579 let(:current_user) { project_bot } 580 581 before do 582 project.add_maintainer(project_bot) 583 end 584 585 it { is_expected.not_to be_allowed(:create_resource_access_tokens)} 586 end 587 end 588 589 describe 'read_prometheus_alerts' do 590 context 'with admin' do 591 let(:current_user) { admin } 592 593 context 'when admin mode is enabled', :enable_admin_mode do 594 it { is_expected.to be_allowed(:read_prometheus_alerts) } 595 end 596 597 context 'when admin mode is disabled' do 598 it { is_expected.to be_disallowed(:read_prometheus_alerts) } 599 end 600 end 601 602 context 'with owner' do 603 let(:current_user) { owner } 604 605 it { is_expected.to be_allowed(:read_prometheus_alerts) } 606 end 607 608 context 'with maintainer' do 609 let(:current_user) { maintainer } 610 611 it { is_expected.to be_allowed(:read_prometheus_alerts) } 612 end 613 614 context 'with developer' do 615 let(:current_user) { developer } 616 617 it { is_expected.to be_disallowed(:read_prometheus_alerts) } 618 end 619 620 context 'with reporter' do 621 let(:current_user) { reporter } 622 623 it { is_expected.to be_disallowed(:read_prometheus_alerts) } 624 end 625 626 context 'with guest' do 627 let(:current_user) { guest } 628 629 it { is_expected.to be_disallowed(:read_prometheus_alerts) } 630 end 631 632 context 'with anonymous' do 633 let(:current_user) { anonymous } 634 635 it { is_expected.to be_disallowed(:read_prometheus_alerts) } 636 end 637 end 638 639 describe 'metrics_dashboard feature' do 640 context 'public project' do 641 let(:project) { public_project } 642 643 context 'feature private' do 644 context 'with reporter' do 645 let(:current_user) { reporter } 646 647 it { is_expected.to be_allowed(:metrics_dashboard) } 648 it { is_expected.to be_allowed(:read_prometheus) } 649 it { is_expected.to be_allowed(:read_deployment) } 650 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 651 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 652 end 653 654 context 'with guest' do 655 let(:current_user) { guest } 656 657 it { is_expected.to be_disallowed(:metrics_dashboard) } 658 end 659 660 context 'with anonymous' do 661 let(:current_user) { anonymous } 662 663 it { is_expected.to be_disallowed(:metrics_dashboard) } 664 end 665 end 666 667 context 'feature enabled' do 668 before do 669 project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED) 670 end 671 672 context 'with reporter' do 673 let(:current_user) { reporter } 674 675 it { is_expected.to be_allowed(:metrics_dashboard) } 676 it { is_expected.to be_allowed(:read_prometheus) } 677 it { is_expected.to be_allowed(:read_deployment) } 678 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 679 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 680 end 681 682 context 'with guest' do 683 let(:current_user) { guest } 684 685 it { is_expected.to be_allowed(:metrics_dashboard) } 686 it { is_expected.to be_allowed(:read_prometheus) } 687 it { is_expected.to be_allowed(:read_deployment) } 688 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 689 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 690 end 691 692 context 'with anonymous' do 693 let(:current_user) { anonymous } 694 695 it { is_expected.to be_allowed(:metrics_dashboard) } 696 it { is_expected.to be_allowed(:read_prometheus) } 697 it { is_expected.to be_allowed(:read_deployment) } 698 it { is_expected.to be_disallowed(:read_metrics_user_starred_dashboard) } 699 it { is_expected.to be_disallowed(:create_metrics_user_starred_dashboard) } 700 end 701 end 702 end 703 704 context 'internal project' do 705 let(:project) { internal_project } 706 707 context 'feature private' do 708 context 'with reporter' do 709 let(:current_user) { reporter } 710 711 it { is_expected.to be_allowed(:metrics_dashboard) } 712 it { is_expected.to be_allowed(:read_prometheus) } 713 it { is_expected.to be_allowed(:read_deployment) } 714 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 715 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 716 end 717 718 context 'with guest' do 719 let(:current_user) { guest } 720 721 it { is_expected.to be_disallowed(:metrics_dashboard) } 722 end 723 724 context 'with anonymous' do 725 let(:current_user) { anonymous } 726 727 it { is_expected.to be_disallowed(:metrics_dashboard)} 728 end 729 end 730 731 context 'feature enabled' do 732 before do 733 project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED) 734 end 735 736 context 'with reporter' do 737 let(:current_user) { reporter } 738 739 it { is_expected.to be_allowed(:metrics_dashboard) } 740 it { is_expected.to be_allowed(:read_prometheus) } 741 it { is_expected.to be_allowed(:read_deployment) } 742 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 743 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 744 end 745 746 context 'with guest' do 747 let(:current_user) { guest } 748 749 it { is_expected.to be_allowed(:metrics_dashboard) } 750 it { is_expected.to be_allowed(:read_prometheus) } 751 it { is_expected.to be_allowed(:read_deployment) } 752 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 753 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 754 end 755 756 context 'with anonymous' do 757 let(:current_user) { anonymous } 758 759 it { is_expected.to be_disallowed(:metrics_dashboard) } 760 end 761 end 762 end 763 764 context 'private project' do 765 let(:project) { private_project } 766 767 context 'feature private' do 768 context 'with reporter' do 769 let(:current_user) { reporter } 770 771 it { is_expected.to be_allowed(:metrics_dashboard) } 772 it { is_expected.to be_allowed(:read_prometheus) } 773 it { is_expected.to be_allowed(:read_deployment) } 774 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 775 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 776 end 777 778 context 'with guest' do 779 let(:current_user) { guest } 780 781 it { is_expected.to be_disallowed(:metrics_dashboard) } 782 end 783 784 context 'with anonymous' do 785 let(:current_user) { anonymous } 786 787 it { is_expected.to be_disallowed(:metrics_dashboard) } 788 end 789 end 790 791 context 'feature enabled' do 792 context 'with reporter' do 793 let(:current_user) { reporter } 794 795 it { is_expected.to be_allowed(:metrics_dashboard) } 796 it { is_expected.to be_allowed(:read_prometheus) } 797 it { is_expected.to be_allowed(:read_deployment) } 798 it { is_expected.to be_allowed(:read_metrics_user_starred_dashboard) } 799 it { is_expected.to be_allowed(:create_metrics_user_starred_dashboard) } 800 end 801 802 context 'with guest' do 803 let(:current_user) { guest } 804 805 it { is_expected.to be_disallowed(:metrics_dashboard) } 806 end 807 808 context 'with anonymous' do 809 let(:current_user) { anonymous } 810 811 it { is_expected.to be_disallowed(:metrics_dashboard) } 812 end 813 end 814 end 815 816 context 'feature disabled' do 817 before do 818 project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::DISABLED) 819 end 820 821 context 'with reporter' do 822 let(:current_user) { reporter } 823 824 it { is_expected.to be_disallowed(:metrics_dashboard) } 825 end 826 827 context 'with guest' do 828 let(:current_user) { guest } 829 830 it { is_expected.to be_disallowed(:metrics_dashboard) } 831 end 832 833 context 'with anonymous' do 834 let(:current_user) { anonymous } 835 836 it { is_expected.to be_disallowed(:metrics_dashboard) } 837 end 838 end 839 end 840 841 context 'deploy key access' do 842 context 'private project' do 843 let(:project) { private_project } 844 let!(:deploy_key) { create(:deploy_key, user: owner) } 845 846 subject { described_class.new(deploy_key, project) } 847 848 context 'when a read deploy key is enabled in the project' do 849 let!(:deploy_keys_project) { create(:deploy_keys_project, project: project, deploy_key: deploy_key) } 850 851 it { is_expected.to be_allowed(:download_code) } 852 it { is_expected.to be_disallowed(:push_code) } 853 it { is_expected.to be_disallowed(:read_project) } 854 end 855 856 context 'when a write deploy key is enabled in the project' do 857 let!(:deploy_keys_project) { create(:deploy_keys_project, :write_access, project: project, deploy_key: deploy_key) } 858 859 it { is_expected.to be_allowed(:download_code) } 860 it { is_expected.to be_allowed(:push_code) } 861 it { is_expected.to be_disallowed(:read_project) } 862 end 863 864 context 'when the deploy key is not enabled in the project' do 865 it { is_expected.to be_disallowed(:download_code) } 866 it { is_expected.to be_disallowed(:push_code) } 867 it { is_expected.to be_disallowed(:read_project) } 868 end 869 end 870 end 871 872 context 'deploy token access' do 873 let!(:project_deploy_token) do 874 create(:project_deploy_token, project: project, deploy_token: deploy_token) 875 end 876 877 subject { described_class.new(deploy_token, project) } 878 879 context 'a deploy token with read_package_registry scope' do 880 let(:deploy_token) { create(:deploy_token, read_package_registry: true) } 881 882 it { is_expected.to be_allowed(:read_package) } 883 it { is_expected.to be_allowed(:read_project) } 884 it { is_expected.to be_disallowed(:create_package) } 885 886 it_behaves_like 'package access with repository disabled' 887 end 888 889 context 'a deploy token with write_package_registry scope' do 890 let(:deploy_token) { create(:deploy_token, write_package_registry: true) } 891 892 it { is_expected.to be_allowed(:create_package) } 893 it { is_expected.to be_allowed(:read_package) } 894 it { is_expected.to be_allowed(:read_project) } 895 it { is_expected.to be_disallowed(:destroy_package) } 896 897 it_behaves_like 'package access with repository disabled' 898 end 899 end 900 901 describe 'create_web_ide_terminal' do 902 context 'with admin' do 903 let(:current_user) { admin } 904 905 context 'when admin mode enabled', :enable_admin_mode do 906 it { is_expected.to be_allowed(:create_web_ide_terminal) } 907 end 908 909 context 'when admin mode disabled' do 910 it { is_expected.to be_disallowed(:create_web_ide_terminal) } 911 end 912 end 913 914 context 'with owner' do 915 let(:current_user) { owner } 916 917 it { is_expected.to be_allowed(:create_web_ide_terminal) } 918 end 919 920 context 'with maintainer' do 921 let(:current_user) { maintainer } 922 923 it { is_expected.to be_allowed(:create_web_ide_terminal) } 924 end 925 926 context 'with developer' do 927 let(:current_user) { developer } 928 929 it { is_expected.to be_disallowed(:create_web_ide_terminal) } 930 end 931 932 context 'with reporter' do 933 let(:current_user) { reporter } 934 935 it { is_expected.to be_disallowed(:create_web_ide_terminal) } 936 end 937 938 context 'with guest' do 939 let(:current_user) { guest } 940 941 it { is_expected.to be_disallowed(:create_web_ide_terminal) } 942 end 943 944 context 'with non member' do 945 let(:current_user) { non_member } 946 947 it { is_expected.to be_disallowed(:create_web_ide_terminal) } 948 end 949 950 context 'with anonymous' do 951 let(:current_user) { anonymous } 952 953 it { is_expected.to be_disallowed(:create_web_ide_terminal) } 954 end 955 end 956 957 describe 'read_repository_graphs' do 958 let(:current_user) { guest } 959 960 before do 961 allow(subject).to receive(:allowed?).with(:read_repository_graphs).and_call_original 962 allow(subject).to receive(:allowed?).with(:download_code).and_return(can_download_code) 963 end 964 965 context 'when user can download_code' do 966 let(:can_download_code) { true } 967 968 it { is_expected.to be_allowed(:read_repository_graphs) } 969 end 970 971 context 'when user cannot download_code' do 972 let(:can_download_code) { false } 973 974 it { is_expected.to be_disallowed(:read_repository_graphs) } 975 end 976 end 977 978 context 'security configuration feature' do 979 %w(guest reporter).each do |role| 980 context role do 981 let(:current_user) { send(role) } 982 983 it 'prevents reading security configuration' do 984 expect_disallowed(:read_security_configuration) 985 end 986 end 987 end 988 989 %w(developer maintainer owner).each do |role| 990 context role do 991 let(:current_user) { send(role) } 992 993 it 'allows reading security configuration' do 994 expect_allowed(:read_security_configuration) 995 end 996 end 997 end 998 end 999 1000 context 'infrastructure google cloud feature' do 1001 %w(guest reporter developer).each do |role| 1002 context role do 1003 let(:current_user) { send(role) } 1004 1005 it 'disallows managing google cloud' do 1006 expect_disallowed(:admin_project_google_cloud) 1007 end 1008 end 1009 end 1010 1011 %w(maintainer owner).each do |role| 1012 context role do 1013 let(:current_user) { send(role) } 1014 1015 it 'allows managing google cloud' do 1016 expect_allowed(:admin_project_google_cloud) 1017 end 1018 end 1019 end 1020 end 1021 1022 describe 'design permissions' do 1023 include DesignManagementTestHelpers 1024 1025 let(:current_user) { guest } 1026 1027 let(:design_permissions) do 1028 %i[read_design_activity read_design] 1029 end 1030 1031 context 'when design management is not available' do 1032 before do 1033 enable_design_management(false) 1034 end 1035 1036 it { is_expected.not_to be_allowed(*design_permissions) } 1037 end 1038 1039 context 'when design management is available' do 1040 before do 1041 enable_design_management 1042 end 1043 1044 it { is_expected.to be_allowed(*design_permissions) } 1045 end 1046 end 1047 1048 describe 'read_build_report_results' do 1049 let(:current_user) { guest } 1050 1051 before do 1052 allow(subject).to receive(:allowed?).with(:read_build_report_results).and_call_original 1053 allow(subject).to receive(:allowed?).with(:read_build).and_return(can_read_build) 1054 allow(subject).to receive(:allowed?).with(:read_pipeline).and_return(can_read_pipeline) 1055 end 1056 1057 context 'when user can read_build and read_pipeline' do 1058 let(:can_read_build) { true } 1059 let(:can_read_pipeline) { true } 1060 1061 it { is_expected.to be_allowed(:read_build_report_results) } 1062 end 1063 1064 context 'when user can read_build but cannot read_pipeline' do 1065 let(:can_read_build) { true } 1066 let(:can_read_pipeline) { false } 1067 1068 it { is_expected.to be_disallowed(:read_build_report_results) } 1069 end 1070 1071 context 'when user cannot read_build but can read_pipeline' do 1072 let(:can_read_build) { false } 1073 let(:can_read_pipeline) { true } 1074 1075 it { is_expected.to be_disallowed(:read_build_report_results) } 1076 end 1077 1078 context 'when user cannot read_build and cannot read_pipeline' do 1079 let(:can_read_build) { false } 1080 let(:can_read_pipeline) { false } 1081 1082 it { is_expected.to be_disallowed(:read_build_report_results) } 1083 end 1084 end 1085 1086 describe 'read_package' do 1087 context 'with admin' do 1088 let(:current_user) { admin } 1089 1090 it { is_expected.to be_allowed(:read_package) } 1091 1092 it_behaves_like 'package access with repository disabled' 1093 end 1094 1095 context 'with owner' do 1096 let(:current_user) { owner } 1097 1098 it { is_expected.to be_allowed(:read_package) } 1099 end 1100 1101 context 'with maintainer' do 1102 let(:current_user) { maintainer } 1103 1104 it { is_expected.to be_allowed(:read_package) } 1105 end 1106 1107 context 'with developer' do 1108 let(:current_user) { developer } 1109 1110 it { is_expected.to be_allowed(:read_package) } 1111 end 1112 1113 context 'with reporter' do 1114 let(:current_user) { reporter } 1115 1116 it { is_expected.to be_allowed(:read_package) } 1117 end 1118 1119 context 'with guest' do 1120 let(:current_user) { guest } 1121 1122 it { is_expected.to be_allowed(:read_package) } 1123 end 1124 1125 context 'with non member' do 1126 let(:current_user) { non_member } 1127 1128 it { is_expected.to be_allowed(:read_package) } 1129 end 1130 1131 context 'with anonymous' do 1132 let(:current_user) { anonymous } 1133 1134 it { is_expected.to be_allowed(:read_package) } 1135 end 1136 end 1137 1138 describe 'read_feature_flag' do 1139 subject { described_class.new(current_user, project) } 1140 1141 context 'with maintainer' do 1142 let(:current_user) { maintainer } 1143 1144 context 'when repository is available' do 1145 it { is_expected.to be_allowed(:read_feature_flag) } 1146 end 1147 1148 context 'when repository is disabled' do 1149 before do 1150 project.project_feature.update!( 1151 merge_requests_access_level: ProjectFeature::DISABLED, 1152 builds_access_level: ProjectFeature::DISABLED, 1153 repository_access_level: ProjectFeature::DISABLED 1154 ) 1155 end 1156 1157 it { is_expected.to be_disallowed(:read_feature_flag) } 1158 end 1159 end 1160 1161 context 'with developer' do 1162 let(:current_user) { developer } 1163 1164 context 'when repository is available' do 1165 it { is_expected.to be_allowed(:read_feature_flag) } 1166 end 1167 end 1168 1169 context 'with reporter' do 1170 let(:current_user) { reporter } 1171 1172 context 'when repository is available' do 1173 it { is_expected.to be_disallowed(:read_feature_flag) } 1174 end 1175 end 1176 end 1177 1178 describe 'read_analytics' do 1179 context 'anonymous user' do 1180 let(:current_user) { anonymous } 1181 1182 it { is_expected.to be_allowed(:read_analytics) } 1183 end 1184 1185 context 'with various analytics features' do 1186 let_it_be(:project_with_analytics_disabled) { create(:project, :analytics_disabled) } 1187 let_it_be(:project_with_analytics_private) { create(:project, :analytics_private) } 1188 let_it_be(:project_with_analytics_enabled) { create(:project, :analytics_enabled) } 1189 1190 before do 1191 project_with_analytics_disabled.add_guest(guest) 1192 project_with_analytics_private.add_guest(guest) 1193 project_with_analytics_enabled.add_guest(guest) 1194 1195 project_with_analytics_disabled.add_reporter(reporter) 1196 project_with_analytics_private.add_reporter(reporter) 1197 project_with_analytics_enabled.add_reporter(reporter) 1198 1199 project_with_analytics_disabled.add_developer(developer) 1200 project_with_analytics_private.add_developer(developer) 1201 project_with_analytics_enabled.add_developer(developer) 1202 end 1203 1204 context 'when analytics is disabled for the project' do 1205 let(:project) { project_with_analytics_disabled } 1206 1207 context 'for guest user' do 1208 let(:current_user) { guest } 1209 1210 it { is_expected.to be_disallowed(:read_cycle_analytics) } 1211 it { is_expected.to be_disallowed(:read_insights) } 1212 it { is_expected.to be_disallowed(:read_repository_graphs) } 1213 it { is_expected.to be_disallowed(:read_ci_cd_analytics) } 1214 end 1215 1216 context 'for reporter user' do 1217 let(:current_user) { reporter } 1218 1219 it { is_expected.to be_disallowed(:read_cycle_analytics) } 1220 it { is_expected.to be_disallowed(:read_insights) } 1221 it { is_expected.to be_disallowed(:read_repository_graphs) } 1222 it { is_expected.to be_disallowed(:read_ci_cd_analytics) } 1223 end 1224 1225 context 'for developer' do 1226 let(:current_user) { developer } 1227 1228 it { is_expected.to be_disallowed(:read_cycle_analytics) } 1229 it { is_expected.to be_disallowed(:read_insights) } 1230 it { is_expected.to be_disallowed(:read_repository_graphs) } 1231 it { is_expected.to be_disallowed(:read_ci_cd_analytics) } 1232 end 1233 end 1234 1235 context 'when analytics is private for the project' do 1236 let(:project) { project_with_analytics_private } 1237 1238 context 'for guest user' do 1239 let(:current_user) { guest } 1240 1241 it { is_expected.to be_allowed(:read_cycle_analytics) } 1242 it { is_expected.to be_allowed(:read_insights) } 1243 it { is_expected.to be_disallowed(:read_repository_graphs) } 1244 it { is_expected.to be_disallowed(:read_ci_cd_analytics) } 1245 end 1246 1247 context 'for reporter user' do 1248 let(:current_user) { reporter } 1249 1250 it { is_expected.to be_allowed(:read_cycle_analytics) } 1251 it { is_expected.to be_allowed(:read_insights) } 1252 it { is_expected.to be_allowed(:read_repository_graphs) } 1253 it { is_expected.to be_allowed(:read_ci_cd_analytics) } 1254 end 1255 1256 context 'for developer' do 1257 let(:current_user) { developer } 1258 1259 it { is_expected.to be_allowed(:read_cycle_analytics) } 1260 it { is_expected.to be_allowed(:read_insights) } 1261 it { is_expected.to be_allowed(:read_repository_graphs) } 1262 it { is_expected.to be_allowed(:read_ci_cd_analytics) } 1263 end 1264 end 1265 1266 context 'when analytics is enabled for the project' do 1267 let(:project) { project_with_analytics_enabled } 1268 1269 context 'for guest user' do 1270 let(:current_user) { guest } 1271 1272 it { is_expected.to be_allowed(:read_cycle_analytics) } 1273 it { is_expected.to be_allowed(:read_insights) } 1274 it { is_expected.to be_disallowed(:read_repository_graphs) } 1275 it { is_expected.to be_disallowed(:read_ci_cd_analytics) } 1276 end 1277 1278 context 'for reporter user' do 1279 let(:current_user) { reporter } 1280 1281 it { is_expected.to be_allowed(:read_cycle_analytics) } 1282 it { is_expected.to be_allowed(:read_insights) } 1283 it { is_expected.to be_allowed(:read_repository_graphs) } 1284 it { is_expected.to be_allowed(:read_ci_cd_analytics) } 1285 end 1286 1287 context 'for developer' do 1288 let(:current_user) { developer } 1289 1290 it { is_expected.to be_allowed(:read_cycle_analytics) } 1291 it { is_expected.to be_allowed(:read_insights) } 1292 it { is_expected.to be_allowed(:read_repository_graphs) } 1293 it { is_expected.to be_allowed(:read_ci_cd_analytics) } 1294 end 1295 end 1296 end 1297 1298 context 'project member' do 1299 let(:project) { private_project } 1300 1301 %w(guest reporter developer maintainer).each do |role| 1302 context role do 1303 let(:current_user) { send(role) } 1304 1305 it { is_expected.to be_allowed(:read_analytics) } 1306 1307 context "without access to Analytics" do 1308 before do 1309 project.project_feature.update!(analytics_access_level: ProjectFeature::DISABLED) 1310 end 1311 1312 it { is_expected.to be_disallowed(:read_analytics) } 1313 end 1314 end 1315 end 1316 end 1317 end 1318 1319 it_behaves_like 'Self-managed Core resource access tokens' 1320 1321 describe 'operations feature' do 1322 using RSpec::Parameterized::TableSyntax 1323 1324 let(:guest_operations_permissions) { [:read_environment, :read_deployment] } 1325 1326 let(:developer_operations_permissions) do 1327 guest_operations_permissions + [ 1328 :read_feature_flag, :read_sentry_issue, :read_alert_management_alert, :read_terraform_state, 1329 :metrics_dashboard, :read_pod_logs, :read_prometheus, :create_feature_flag, 1330 :create_environment, :create_deployment, :update_feature_flag, :update_environment, 1331 :update_sentry_issue, :update_alert_management_alert, :update_deployment, 1332 :destroy_feature_flag, :destroy_environment, :admin_feature_flag 1333 ] 1334 end 1335 1336 let(:maintainer_operations_permissions) do 1337 developer_operations_permissions + [ 1338 :read_cluster, :create_cluster, :update_cluster, :admin_environment, 1339 :admin_cluster, :admin_terraform_state, :admin_deployment 1340 ] 1341 end 1342 1343 where(:project_visibility, :access_level, :role, :allowed) do 1344 :public | ProjectFeature::ENABLED | :maintainer | true 1345 :public | ProjectFeature::ENABLED | :developer | true 1346 :public | ProjectFeature::ENABLED | :guest | true 1347 :public | ProjectFeature::ENABLED | :anonymous | true 1348 :public | ProjectFeature::PRIVATE | :maintainer | true 1349 :public | ProjectFeature::PRIVATE | :developer | true 1350 :public | ProjectFeature::PRIVATE | :guest | true 1351 :public | ProjectFeature::PRIVATE | :anonymous | false 1352 :public | ProjectFeature::DISABLED | :maintainer | false 1353 :public | ProjectFeature::DISABLED | :developer | false 1354 :public | ProjectFeature::DISABLED | :guest | false 1355 :public | ProjectFeature::DISABLED | :anonymous | false 1356 :internal | ProjectFeature::ENABLED | :maintainer | true 1357 :internal | ProjectFeature::ENABLED | :developer | true 1358 :internal | ProjectFeature::ENABLED | :guest | true 1359 :internal | ProjectFeature::ENABLED | :anonymous | false 1360 :internal | ProjectFeature::PRIVATE | :maintainer | true 1361 :internal | ProjectFeature::PRIVATE | :developer | true 1362 :internal | ProjectFeature::PRIVATE | :guest | true 1363 :internal | ProjectFeature::PRIVATE | :anonymous | false 1364 :internal | ProjectFeature::DISABLED | :maintainer | false 1365 :internal | ProjectFeature::DISABLED | :developer | false 1366 :internal | ProjectFeature::DISABLED | :guest | false 1367 :internal | ProjectFeature::DISABLED | :anonymous | false 1368 :private | ProjectFeature::ENABLED | :maintainer | true 1369 :private | ProjectFeature::ENABLED | :developer | true 1370 :private | ProjectFeature::ENABLED | :guest | false 1371 :private | ProjectFeature::ENABLED | :anonymous | false 1372 :private | ProjectFeature::PRIVATE | :maintainer | true 1373 :private | ProjectFeature::PRIVATE | :developer | true 1374 :private | ProjectFeature::PRIVATE | :guest | false 1375 :private | ProjectFeature::PRIVATE | :anonymous | false 1376 :private | ProjectFeature::DISABLED | :maintainer | false 1377 :private | ProjectFeature::DISABLED | :developer | false 1378 :private | ProjectFeature::DISABLED | :guest | false 1379 :private | ProjectFeature::DISABLED | :anonymous | false 1380 end 1381 1382 with_them do 1383 let(:current_user) { user_subject(role) } 1384 let(:project) { project_subject(project_visibility) } 1385 1386 it 'allows/disallows the abilities based on the operation feature access level' do 1387 project.project_feature.update!(operations_access_level: access_level) 1388 1389 if allowed 1390 expect_allowed(*permissions_abilities(role)) 1391 else 1392 expect_disallowed(*permissions_abilities(role)) 1393 end 1394 end 1395 1396 def project_subject(project_type) 1397 case project_type 1398 when :public 1399 public_project 1400 when :internal 1401 internal_project 1402 else 1403 private_project 1404 end 1405 end 1406 1407 def user_subject(role) 1408 case role 1409 when :maintainer 1410 maintainer 1411 when :developer 1412 developer 1413 when :guest 1414 guest 1415 when :anonymous 1416 anonymous 1417 end 1418 end 1419 1420 def permissions_abilities(role) 1421 case role 1422 when :maintainer 1423 maintainer_operations_permissions 1424 when :developer 1425 developer_operations_permissions 1426 else 1427 guest_operations_permissions 1428 end 1429 end 1430 end 1431 end 1432 1433 describe 'access_security_and_compliance' do 1434 context 'when the "Security & Compliance" is enabled' do 1435 before do 1436 project.project_feature.update!(security_and_compliance_access_level: Featurable::PRIVATE) 1437 end 1438 1439 %w[owner maintainer developer].each do |role| 1440 context "when the role is #{role}" do 1441 let(:current_user) { public_send(role) } 1442 1443 it { is_expected.to be_allowed(:access_security_and_compliance) } 1444 end 1445 end 1446 1447 context 'with admin' do 1448 let(:current_user) { admin } 1449 1450 context 'when admin mode enabled', :enable_admin_mode do 1451 it { is_expected.to be_allowed(:access_security_and_compliance) } 1452 end 1453 1454 context 'when admin mode disabled' do 1455 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1456 end 1457 end 1458 1459 %w[reporter guest].each do |role| 1460 context "when the role is #{role}" do 1461 let(:current_user) { public_send(role) } 1462 1463 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1464 end 1465 end 1466 1467 context 'with non member' do 1468 let(:current_user) { non_member } 1469 1470 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1471 end 1472 1473 context 'with anonymous' do 1474 let(:current_user) { anonymous } 1475 1476 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1477 end 1478 end 1479 1480 context 'when the "Security & Compliance" is not enabled' do 1481 before do 1482 project.project_feature.update!(security_and_compliance_access_level: Featurable::DISABLED) 1483 end 1484 1485 %w[owner maintainer developer reporter guest].each do |role| 1486 context "when the role is #{role}" do 1487 let(:current_user) { public_send(role) } 1488 1489 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1490 end 1491 end 1492 1493 context 'with admin' do 1494 let(:current_user) { admin } 1495 1496 context 'when admin mode enabled', :enable_admin_mode do 1497 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1498 end 1499 1500 context 'when admin mode disabled' do 1501 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1502 end 1503 end 1504 1505 context 'with non member' do 1506 let(:current_user) { non_member } 1507 1508 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1509 end 1510 1511 context 'with anonymous' do 1512 let(:current_user) { anonymous } 1513 1514 it { is_expected.to be_disallowed(:access_security_and_compliance) } 1515 end 1516 end 1517 end 1518 1519 describe 'when user is authenticated via CI_JOB_TOKEN', :request_store do 1520 using RSpec::Parameterized::TableSyntax 1521 1522 where(:project_visibility, :user_role, :external_user, :scope_project_type, :token_scope_enabled, :result) do 1523 :private | :reporter | false | :same | true | true 1524 :private | :reporter | false | :same | false | true 1525 :private | :reporter | false | :different | true | false 1526 :private | :reporter | false | :different | false | true 1527 :private | :guest | false | :same | true | true 1528 :private | :guest | false | :same | false | true 1529 :private | :guest | false | :different | true | false 1530 :private | :guest | false | :different | false | true 1531 1532 :internal | :reporter | false | :same | true | true 1533 :internal | :reporter | true | :same | true | true 1534 :internal | :reporter | false | :same | false | true 1535 :internal | :reporter | false | :different | true | true 1536 :internal | :reporter | true | :different | true | false 1537 :internal | :reporter | false | :different | false | true 1538 :internal | :guest | false | :same | true | true 1539 :internal | :guest | true | :same | true | true 1540 :internal | :guest | false | :same | false | true 1541 :internal | :guest | false | :different | true | true 1542 :internal | :guest | true | :different | true | false 1543 :internal | :guest | false | :different | false | true 1544 1545 :public | :reporter | false | :same | true | true 1546 :public | :reporter | false | :same | false | true 1547 :public | :reporter | false | :different | true | true 1548 :public | :reporter | false | :different | false | true 1549 :public | :guest | false | :same | true | true 1550 :public | :guest | false | :same | false | true 1551 :public | :guest | false | :different | true | true 1552 :public | :guest | false | :different | false | true 1553 end 1554 1555 with_them do 1556 let(:current_user) { public_send(user_role) } 1557 let(:project) { public_send("#{project_visibility}_project") } 1558 let(:job) { build_stubbed(:ci_build, project: scope_project, user: current_user) } 1559 1560 let(:scope_project) do 1561 if scope_project_type == :same 1562 project 1563 else 1564 create(:project, :private) 1565 end 1566 end 1567 1568 before do 1569 current_user.set_ci_job_token_scope!(job) 1570 current_user.external = external_user 1571 scope_project.update!(ci_job_token_scope_enabled: token_scope_enabled) 1572 end 1573 1574 it "enforces the expected permissions" do 1575 if result 1576 is_expected.to be_allowed("#{user_role}_access".to_sym) 1577 else 1578 is_expected.to be_disallowed("#{user_role}_access".to_sym) 1579 end 1580 end 1581 end 1582 end 1583 1584 describe 'container_image policies' do 1585 using RSpec::Parameterized::TableSyntax 1586 1587 # These are permissions that admins should not have when the project is private 1588 # or the container registry is private. 1589 let(:admin_excluded_permissions) { [:build_read_container_image] } 1590 1591 let(:anonymous_operations_permissions) { [:read_container_image] } 1592 let(:guest_operations_permissions) { anonymous_operations_permissions + [:build_read_container_image] } 1593 1594 let(:developer_operations_permissions) do 1595 guest_operations_permissions + [ 1596 :create_container_image, :update_container_image, :destroy_container_image 1597 ] 1598 end 1599 1600 let(:maintainer_operations_permissions) do 1601 developer_operations_permissions + [ 1602 :admin_container_image 1603 ] 1604 end 1605 1606 let(:all_permissions) { maintainer_operations_permissions } 1607 1608 where(:project_visibility, :access_level, :role, :allowed) do 1609 :public | ProjectFeature::ENABLED | :admin | true 1610 :public | ProjectFeature::ENABLED | :owner | true 1611 :public | ProjectFeature::ENABLED | :maintainer | true 1612 :public | ProjectFeature::ENABLED | :developer | true 1613 :public | ProjectFeature::ENABLED | :reporter | true 1614 :public | ProjectFeature::ENABLED | :guest | true 1615 :public | ProjectFeature::ENABLED | :anonymous | true 1616 :public | ProjectFeature::PRIVATE | :admin | true 1617 :public | ProjectFeature::PRIVATE | :owner | true 1618 :public | ProjectFeature::PRIVATE | :maintainer | true 1619 :public | ProjectFeature::PRIVATE | :developer | true 1620 :public | ProjectFeature::PRIVATE | :reporter | true 1621 :public | ProjectFeature::PRIVATE | :guest | false 1622 :public | ProjectFeature::PRIVATE | :anonymous | false 1623 :public | ProjectFeature::DISABLED | :admin | false 1624 :public | ProjectFeature::DISABLED | :owner | false 1625 :public | ProjectFeature::DISABLED | :maintainer | false 1626 :public | ProjectFeature::DISABLED | :developer | false 1627 :public | ProjectFeature::DISABLED | :reporter | false 1628 :public | ProjectFeature::DISABLED | :guest | false 1629 :public | ProjectFeature::DISABLED | :anonymous | false 1630 :internal | ProjectFeature::ENABLED | :admin | true 1631 :internal | ProjectFeature::ENABLED | :owner | true 1632 :internal | ProjectFeature::ENABLED | :maintainer | true 1633 :internal | ProjectFeature::ENABLED | :developer | true 1634 :internal | ProjectFeature::ENABLED | :reporter | true 1635 :internal | ProjectFeature::ENABLED | :guest | true 1636 :internal | ProjectFeature::ENABLED | :anonymous | false 1637 :internal | ProjectFeature::PRIVATE | :admin | true 1638 :internal | ProjectFeature::PRIVATE | :owner | true 1639 :internal | ProjectFeature::PRIVATE | :maintainer | true 1640 :internal | ProjectFeature::PRIVATE | :developer | true 1641 :internal | ProjectFeature::PRIVATE | :reporter | true 1642 :internal | ProjectFeature::PRIVATE | :guest | false 1643 :internal | ProjectFeature::PRIVATE | :anonymous | false 1644 :internal | ProjectFeature::DISABLED | :admin | false 1645 :internal | ProjectFeature::DISABLED | :owner | false 1646 :internal | ProjectFeature::DISABLED | :maintainer | false 1647 :internal | ProjectFeature::DISABLED | :developer | false 1648 :internal | ProjectFeature::DISABLED | :reporter | false 1649 :internal | ProjectFeature::DISABLED | :guest | false 1650 :internal | ProjectFeature::DISABLED | :anonymous | false 1651 :private | ProjectFeature::ENABLED | :admin | true 1652 :private | ProjectFeature::ENABLED | :owner | true 1653 :private | ProjectFeature::ENABLED | :maintainer | true 1654 :private | ProjectFeature::ENABLED | :developer | true 1655 :private | ProjectFeature::ENABLED | :reporter | true 1656 :private | ProjectFeature::ENABLED | :guest | false 1657 :private | ProjectFeature::ENABLED | :anonymous | false 1658 :private | ProjectFeature::PRIVATE | :admin | true 1659 :private | ProjectFeature::PRIVATE | :owner | true 1660 :private | ProjectFeature::PRIVATE | :maintainer | true 1661 :private | ProjectFeature::PRIVATE | :developer | true 1662 :private | ProjectFeature::PRIVATE | :reporter | true 1663 :private | ProjectFeature::PRIVATE | :guest | false 1664 :private | ProjectFeature::PRIVATE | :anonymous | false 1665 :private | ProjectFeature::DISABLED | :admin | false 1666 :private | ProjectFeature::DISABLED | :owner | false 1667 :private | ProjectFeature::DISABLED | :maintainer | false 1668 :private | ProjectFeature::DISABLED | :developer | false 1669 :private | ProjectFeature::DISABLED | :reporter | false 1670 :private | ProjectFeature::DISABLED | :guest | false 1671 :private | ProjectFeature::DISABLED | :anonymous | false 1672 end 1673 1674 with_them do 1675 let(:current_user) { send(role) } 1676 let(:project) { send("#{project_visibility}_project") } 1677 1678 before do 1679 enable_admin_mode!(admin) if role == :admin 1680 project.project_feature.update!(container_registry_access_level: access_level) 1681 end 1682 1683 it 'allows/disallows the abilities based on the container_registry feature access level' do 1684 if allowed 1685 expect_allowed(*permissions_abilities(role)) 1686 expect_disallowed(*(all_permissions - permissions_abilities(role))) 1687 else 1688 expect_disallowed(*all_permissions) 1689 end 1690 end 1691 1692 it 'allows build_read_container_image to admins who are also team members' do 1693 if allowed && role == :admin 1694 project.add_reporter(current_user) 1695 1696 expect_allowed(:build_read_container_image) 1697 end 1698 end 1699 1700 def permissions_abilities(role) 1701 case role 1702 when :admin 1703 if project_visibility == :private || access_level == ProjectFeature::PRIVATE 1704 maintainer_operations_permissions - admin_excluded_permissions 1705 else 1706 maintainer_operations_permissions 1707 end 1708 when :maintainer, :owner 1709 maintainer_operations_permissions 1710 when :developer 1711 developer_operations_permissions 1712 when :reporter, :guest 1713 guest_operations_permissions 1714 when :anonymous 1715 anonymous_operations_permissions 1716 else 1717 raise "Unknown role #{role}" 1718 end 1719 end 1720 end 1721 end 1722 1723 describe 'update_runners_registration_token' do 1724 context 'when anonymous' do 1725 let(:current_user) { anonymous } 1726 1727 it { is_expected.not_to be_allowed(:update_runners_registration_token) } 1728 end 1729 1730 context 'admin' do 1731 let(:current_user) { create(:admin) } 1732 1733 context 'when admin mode is enabled', :enable_admin_mode do 1734 it { is_expected.to be_allowed(:update_runners_registration_token) } 1735 end 1736 1737 context 'when admin mode is disabled' do 1738 it { is_expected.to be_disallowed(:update_runners_registration_token) } 1739 end 1740 end 1741 1742 %w(guest reporter developer).each do |role| 1743 context role do 1744 let(:current_user) { send(role) } 1745 1746 it { is_expected.to be_disallowed(:update_runners_registration_token) } 1747 end 1748 end 1749 1750 %w(maintainer owner).each do |role| 1751 context role do 1752 let(:current_user) { send(role) } 1753 1754 it { is_expected.to be_allowed(:update_runners_registration_token) } 1755 end 1756 end 1757 end 1758end 1759