Commit 2fc236177f70244101b285bde8ee6a77f779c0ce
Exists in
master
and in
4 other branches
Merge pull request #3801 from holdtotherod/feature/internally-public-projects
Internally public projects
Showing
8 changed files
with
276 additions
and
4 deletions
Show diff stats
app/controllers/application_controller.rb
| ... | ... | @@ -88,7 +88,7 @@ class ApplicationController < ActionController::Base |
| 88 | 88 | end |
| 89 | 89 | |
| 90 | 90 | def authorize_code_access! |
| 91 | - return access_denied! unless can?(current_user, :download_code, project) | |
| 91 | + return access_denied! unless can?(current_user, :download_code, project) or project.public? | |
| 92 | 92 | end |
| 93 | 93 | |
| 94 | 94 | def authorize_create_team! | ... | ... |
app/models/ability.rb
app/views/projects/_form.html.haml
| ... | ... | @@ -48,7 +48,7 @@ |
| 48 | 48 | Public mode: |
| 49 | 49 | .control-group |
| 50 | 50 | = f.label :public, class: 'control-label' do |
| 51 | - %span Public clone access | |
| 51 | + %span Public access | |
| 52 | 52 | .controls |
| 53 | 53 | = f.check_box :public |
| 54 | 54 | %span.descr |
| ... | ... | @@ -56,6 +56,8 @@ |
| 56 | 56 | %em without any |
| 57 | 57 | authentication. |
| 58 | 58 | It will also be listed on the #{link_to "public access directory", public_root_path}. |
| 59 | + %em Any | |
| 60 | + user will have #{link_to "Guest", help_permissions_path} permissions on the repository. | |
| 59 | 61 | |
| 60 | 62 | %fieldset.features |
| 61 | 63 | %legend | ... | ... |
app/views/public/projects/index.html.haml
| ... | ... | @@ -9,7 +9,10 @@ |
| 9 | 9 | %li.clearfix |
| 10 | 10 | %h5 |
| 11 | 11 | %i.icon-share |
| 12 | - = project.name_with_namespace | |
| 12 | + - if current_user | |
| 13 | + = link_to_project project | |
| 14 | + - else | |
| 15 | + = project.name_with_namespace | |
| 13 | 16 | .pull-right |
| 14 | 17 | %pre.dark.tiny git clone #{project.http_url_to_repo} |
| 15 | 18 | %p.description | ... | ... |
features/steps/shared/paths.rb
| ... | ... | @@ -263,6 +263,14 @@ module SharedPaths |
| 263 | 263 | visit project_wiki_path(@project, :home) |
| 264 | 264 | end |
| 265 | 265 | |
| 266 | + # ---------------------------------------- | |
| 267 | + # Public Projects | |
| 268 | + # ---------------------------------------- | |
| 269 | + | |
| 270 | + Given 'I visit the public projects area' do | |
| 271 | + visit public_root_path | |
| 272 | + end | |
| 273 | + | |
| 266 | 274 | def root_ref |
| 267 | 275 | @project.repository.root_ref |
| 268 | 276 | end | ... | ... |
spec/features/security/project_access_spec.rb
| ... | ... | @@ -229,4 +229,246 @@ describe "Application access" do |
| 229 | 229 | it { should be_denied_for :visitor } |
| 230 | 230 | end |
| 231 | 231 | end |
| 232 | + | |
| 233 | + | |
| 234 | + describe "PublicProject" do | |
| 235 | + let(:project) { create(:project_with_code) } | |
| 236 | + | |
| 237 | + let(:master) { create(:user) } | |
| 238 | + let(:guest) { create(:user) } | |
| 239 | + let(:reporter) { create(:user) } | |
| 240 | + | |
| 241 | + let(:admin) { create(:user) } | |
| 242 | + | |
| 243 | + before do | |
| 244 | + # public project | |
| 245 | + project.public = true | |
| 246 | + project.save! | |
| 247 | + | |
| 248 | + # full access | |
| 249 | + project.team << [master, :master] | |
| 250 | + | |
| 251 | + # readonly | |
| 252 | + project.team << [reporter, :reporter] | |
| 253 | + | |
| 254 | + end | |
| 255 | + | |
| 256 | + describe "Project should be public" do | |
| 257 | + subject { project } | |
| 258 | + | |
| 259 | + its(:public?) { should be_true } | |
| 260 | + end | |
| 261 | + | |
| 262 | + describe "GET /project_code" do | |
| 263 | + subject { project_path(project) } | |
| 264 | + | |
| 265 | + it { should be_allowed_for master } | |
| 266 | + it { should be_allowed_for reporter } | |
| 267 | + it { should be_allowed_for admin } | |
| 268 | + it { should be_allowed_for guest } | |
| 269 | + it { should be_allowed_for :user } | |
| 270 | + it { should be_denied_for :visitor } | |
| 271 | + end | |
| 272 | + | |
| 273 | + describe "GET /project_code/tree/master" do | |
| 274 | + subject { project_tree_path(project, project.repository.root_ref) } | |
| 275 | + | |
| 276 | + it { should be_allowed_for master } | |
| 277 | + it { should be_allowed_for reporter } | |
| 278 | + it { should be_allowed_for :admin } | |
| 279 | + it { should be_allowed_for guest } | |
| 280 | + it { should be_allowed_for :user } | |
| 281 | + it { should be_denied_for :visitor } | |
| 282 | + end | |
| 283 | + | |
| 284 | + describe "GET /project_code/commits/master" do | |
| 285 | + subject { project_commits_path(project, project.repository.root_ref, limit: 1) } | |
| 286 | + | |
| 287 | + it { should be_allowed_for master } | |
| 288 | + it { should be_allowed_for reporter } | |
| 289 | + it { should be_allowed_for :admin } | |
| 290 | + it { should be_allowed_for guest } | |
| 291 | + it { should be_allowed_for :user } | |
| 292 | + it { should be_denied_for :visitor } | |
| 293 | + end | |
| 294 | + | |
| 295 | + describe "GET /project_code/commit/:sha" do | |
| 296 | + subject { project_commit_path(project, project.repository.commit) } | |
| 297 | + | |
| 298 | + it { should be_allowed_for master } | |
| 299 | + it { should be_allowed_for reporter } | |
| 300 | + it { should be_allowed_for :admin } | |
| 301 | + it { should be_allowed_for guest } | |
| 302 | + it { should be_allowed_for :user } | |
| 303 | + it { should be_denied_for :visitor } | |
| 304 | + end | |
| 305 | + | |
| 306 | + describe "GET /project_code/compare" do | |
| 307 | + subject { project_compare_index_path(project) } | |
| 308 | + | |
| 309 | + it { should be_allowed_for master } | |
| 310 | + it { should be_allowed_for reporter } | |
| 311 | + it { should be_allowed_for :admin } | |
| 312 | + it { should be_allowed_for guest } | |
| 313 | + it { should be_allowed_for :user } | |
| 314 | + it { should be_denied_for :visitor } | |
| 315 | + end | |
| 316 | + | |
| 317 | + describe "GET /project_code/team" do | |
| 318 | + subject { project_team_index_path(project) } | |
| 319 | + | |
| 320 | + it { should be_allowed_for master } | |
| 321 | + it { should be_allowed_for reporter } | |
| 322 | + it { should be_allowed_for :admin } | |
| 323 | + it { should be_allowed_for guest } | |
| 324 | + it { should be_allowed_for :user } | |
| 325 | + it { should be_denied_for :visitor } | |
| 326 | + end | |
| 327 | + | |
| 328 | + describe "GET /project_code/wall" do | |
| 329 | + subject { project_wall_path(project) } | |
| 330 | + | |
| 331 | + it { should be_allowed_for master } | |
| 332 | + it { should be_allowed_for reporter } | |
| 333 | + it { should be_allowed_for :admin } | |
| 334 | + it { should be_allowed_for guest } | |
| 335 | + it { should be_allowed_for :user } | |
| 336 | + it { should be_denied_for :visitor } | |
| 337 | + end | |
| 338 | + | |
| 339 | + describe "GET /project_code/blob" do | |
| 340 | + before do | |
| 341 | + commit = project.repository.commit | |
| 342 | + path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name | |
| 343 | + @blob_path = project_blob_path(project, File.join(commit.id, path)) | |
| 344 | + end | |
| 345 | + | |
| 346 | + it { @blob_path.should be_allowed_for master } | |
| 347 | + it { @blob_path.should be_allowed_for reporter } | |
| 348 | + it { @blob_path.should be_allowed_for :admin } | |
| 349 | + it { @blob_path.should be_allowed_for guest } | |
| 350 | + it { @blob_path.should be_allowed_for :user } | |
| 351 | + it { @blob_path.should be_denied_for :visitor } | |
| 352 | + end | |
| 353 | + | |
| 354 | + describe "GET /project_code/edit" do | |
| 355 | + subject { edit_project_path(project) } | |
| 356 | + | |
| 357 | + it { should be_allowed_for master } | |
| 358 | + it { should be_denied_for reporter } | |
| 359 | + it { should be_allowed_for :admin } | |
| 360 | + it { should be_denied_for guest } | |
| 361 | + it { should be_denied_for :user } | |
| 362 | + it { should be_denied_for :visitor } | |
| 363 | + end | |
| 364 | + | |
| 365 | + describe "GET /project_code/deploy_keys" do | |
| 366 | + subject { project_deploy_keys_path(project) } | |
| 367 | + | |
| 368 | + it { should be_allowed_for master } | |
| 369 | + it { should be_denied_for reporter } | |
| 370 | + it { should be_allowed_for :admin } | |
| 371 | + it { should be_denied_for guest } | |
| 372 | + it { should be_denied_for :user } | |
| 373 | + it { should be_denied_for :visitor } | |
| 374 | + end | |
| 375 | + | |
| 376 | + describe "GET /project_code/issues" do | |
| 377 | + subject { project_issues_path(project) } | |
| 378 | + | |
| 379 | + it { should be_allowed_for master } | |
| 380 | + it { should be_allowed_for reporter } | |
| 381 | + it { should be_allowed_for :admin } | |
| 382 | + it { should be_allowed_for guest } | |
| 383 | + it { should be_allowed_for :user } | |
| 384 | + it { should be_denied_for :visitor } | |
| 385 | + end | |
| 386 | + | |
| 387 | + describe "GET /project_code/snippets" do | |
| 388 | + subject { project_snippets_path(project) } | |
| 389 | + | |
| 390 | + it { should be_allowed_for master } | |
| 391 | + it { should be_allowed_for reporter } | |
| 392 | + it { should be_allowed_for :admin } | |
| 393 | + it { should be_allowed_for guest } | |
| 394 | + it { should be_allowed_for :user } | |
| 395 | + it { should be_denied_for :visitor } | |
| 396 | + end | |
| 397 | + | |
| 398 | + describe "GET /project_code/snippets/new" do | |
| 399 | + subject { new_project_snippet_path(project) } | |
| 400 | + | |
| 401 | + it { should be_allowed_for master } | |
| 402 | + it { should be_allowed_for reporter } | |
| 403 | + it { should be_allowed_for :admin } | |
| 404 | + it { should be_denied_for guest } | |
| 405 | + it { should be_denied_for :user } | |
| 406 | + it { should be_denied_for :visitor } | |
| 407 | + end | |
| 408 | + | |
| 409 | + describe "GET /project_code/merge_requests" do | |
| 410 | + subject { project_merge_requests_path(project) } | |
| 411 | + | |
| 412 | + it { should be_allowed_for master } | |
| 413 | + it { should be_allowed_for reporter } | |
| 414 | + it { should be_allowed_for :admin } | |
| 415 | + it { should be_allowed_for guest } | |
| 416 | + it { should be_allowed_for :user } | |
| 417 | + it { should be_denied_for :visitor } | |
| 418 | + end | |
| 419 | + | |
| 420 | + describe "GET /project_code/repository" do | |
| 421 | + subject { project_repository_path(project) } | |
| 422 | + | |
| 423 | + it { should be_allowed_for master } | |
| 424 | + it { should be_allowed_for reporter } | |
| 425 | + it { should be_allowed_for :admin } | |
| 426 | + it { should be_allowed_for guest } | |
| 427 | + it { should be_allowed_for :user } | |
| 428 | + it { should be_denied_for :visitor } | |
| 429 | + end | |
| 430 | + | |
| 431 | + describe "GET /project_code/repository/branches" do | |
| 432 | + subject { branches_project_repository_path(project) } | |
| 433 | + | |
| 434 | + before do | |
| 435 | + # Speed increase | |
| 436 | + Project.any_instance.stub(:branches).and_return([]) | |
| 437 | + end | |
| 438 | + | |
| 439 | + it { should be_allowed_for master } | |
| 440 | + it { should be_allowed_for reporter } | |
| 441 | + it { should be_allowed_for :admin } | |
| 442 | + it { should be_allowed_for guest } | |
| 443 | + it { should be_allowed_for :user } | |
| 444 | + it { should be_denied_for :visitor } | |
| 445 | + end | |
| 446 | + | |
| 447 | + describe "GET /project_code/repository/tags" do | |
| 448 | + subject { tags_project_repository_path(project) } | |
| 449 | + | |
| 450 | + before do | |
| 451 | + # Speed increase | |
| 452 | + Project.any_instance.stub(:tags).and_return([]) | |
| 453 | + end | |
| 454 | + | |
| 455 | + it { should be_allowed_for master } | |
| 456 | + it { should be_allowed_for reporter } | |
| 457 | + it { should be_allowed_for :admin } | |
| 458 | + it { should be_allowed_for guest } | |
| 459 | + it { should be_allowed_for :user } | |
| 460 | + it { should be_denied_for :visitor } | |
| 461 | + end | |
| 462 | + | |
| 463 | + describe "GET /project_code/hooks" do | |
| 464 | + subject { project_hooks_path(project) } | |
| 465 | + | |
| 466 | + it { should be_allowed_for master } | |
| 467 | + it { should be_allowed_for reporter } | |
| 468 | + it { should be_allowed_for :admin } | |
| 469 | + it { should be_allowed_for guest } | |
| 470 | + it { should be_allowed_for :user } | |
| 471 | + it { should be_denied_for :visitor } | |
| 472 | + end | |
| 473 | + end | |
| 232 | 474 | end | ... | ... |