Commit 91571c078dee6297a17afecb6dc071ce882c82be
1 parent
1284f21c
Exists in
spb-stable
and in
3 other branches
User pages are visible to users without login
... if the user is authorized to at least one public project.
Showing
19 changed files
with
229 additions
and
71 deletions
Show diff stats
CHANGELOG
... | ... | @@ -2,7 +2,7 @@ v 6.6.0 |
2 | 2 | - Permissions: Developer now can manage issue tracker (modify any issue) |
3 | 3 | - Improve Code Compare page performance |
4 | 4 | - Group avatar |
5 | - - Pygments.rb replaced with highlight.js | |
5 | + - Pygments.rb replaced with highlight.js | |
6 | 6 | - Improve Merge request diff store logic |
7 | 7 | - Improve render performnace for MR show page |
8 | 8 | - Fixed Assembla hardcoded project name |
... | ... | @@ -12,6 +12,7 @@ v 6.6.0 |
12 | 12 | - Mobile UI improvements (Drew Blessing) |
13 | 13 | - Fix block/remove UI for admin::users#show page |
14 | 14 | - Show users' group membership on users' activity page |
15 | + - User pages are visible without login if user is authorized to a public project | |
15 | 16 | |
16 | 17 | v 6.5.1 |
17 | 18 | - Fix branch selectbox when create merge request from fork |
... | ... | @@ -45,7 +46,7 @@ v6.4.3 |
45 | 46 | v6.4.2 |
46 | 47 | - Fixed wrong behaviour of script/upgrade.rb |
47 | 48 | |
48 | -v6.4.1 | |
49 | +v6.4.1 | |
49 | 50 | - Fixed bug with repository rename |
50 | 51 | - Fixed bug with project transfer |
51 | 52 | ... | ... |
app/assets/stylesheets/sections/header.scss
... | ... | @@ -56,7 +56,7 @@ header { |
56 | 56 | font-size: 18px; |
57 | 57 | |
58 | 58 | .app_logo { margin-left: -15px; } |
59 | - .project_name { | |
59 | + .title { | |
60 | 60 | display: inline-block; |
61 | 61 | overflow: hidden; |
62 | 62 | text-overflow: ellipsis; |
... | ... | @@ -127,7 +127,7 @@ header { |
127 | 127 | * Project / Area name |
128 | 128 | * |
129 | 129 | */ |
130 | - .project_name { | |
130 | + .title { | |
131 | 131 | position: relative; |
132 | 132 | float: left; |
133 | 133 | margin: 0; |
... | ... | @@ -227,7 +227,7 @@ header { |
227 | 227 | } |
228 | 228 | } |
229 | 229 | } |
230 | - .project_name { | |
230 | + .title { | |
231 | 231 | a { |
232 | 232 | color: #BBB; |
233 | 233 | &:hover { | ... | ... |
app/controllers/users_controller.rb
1 | 1 | class UsersController < ApplicationController |
2 | - layout 'navless' | |
2 | + | |
3 | + skip_before_filter :authenticate_user!, only: [:show] | |
4 | + layout :determine_layout | |
3 | 5 | |
4 | 6 | def show |
5 | - @user = User.find_by!(username: params[:username]) | |
6 | - @projects = @user.authorized_projects.where(id: current_user.authorized_projects.pluck(:id)).includes(:namespace) | |
7 | + @user = User.find_by_username!(params[:username]) | |
8 | + @projects = @user.authorized_projects.includes(:namespace).select {|project| can?(current_user, :read_project, project)} | |
9 | + if !current_user && @projects.empty? | |
10 | + return authenticate_user! | |
11 | + end | |
7 | 12 | @events = @user.recent_events.where(project_id: @projects.map(&:id)).limit(20) |
8 | - | |
9 | 13 | @title = @user.name |
10 | 14 | end |
15 | + | |
16 | + def determine_layout | |
17 | + if current_user | |
18 | + 'navless' | |
19 | + else | |
20 | + 'public_users' | |
21 | + end | |
22 | + end | |
11 | 23 | end | ... | ... |
app/views/help/public_access.html.haml
... | ... | @@ -44,3 +44,18 @@ |
44 | 44 | %li Go to your project dashboard |
45 | 45 | %li Click on the "Edit" tab |
46 | 46 | %li Change "Visibility Level" |
47 | + | |
48 | + %h4 Visibility of users | |
49 | + The public page of users, located at | |
50 | + = succeed "," do | |
51 | + %code u/username | |
52 | + is visible if either: | |
53 | + %ul | |
54 | + %li | |
55 | + You are logged in. | |
56 | + %li | |
57 | + %p | |
58 | + You are logged out, and the target user is authorized to (is Guest, Reporter, etc.) | |
59 | + at least one public project. | |
60 | + %p Otherwise, you will be redirected to the sign in page. | |
61 | + When visiting the public page of an user, you will only see listed projects which you can view yourself. | ... | ... |
app/views/layouts/_head_panel.html.haml
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do |
7 | 7 | %h1 GITLAB |
8 | 8 | %span.separator |
9 | - %h1.project_name= title | |
9 | + %h1.title= title | |
10 | 10 | |
11 | 11 | %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} |
12 | 12 | %span.sr-only Toggle navigation | ... | ... |
app/views/layouts/_public_head_panel.html.haml
... | ... | @@ -6,11 +6,7 @@ |
6 | 6 | = link_to public_root_path, class: "home" do |
7 | 7 | %h1 GITLAB |
8 | 8 | %span.separator |
9 | - %h1.project_name | |
10 | - - if @project | |
11 | - = project_title(@project) | |
12 | - - else | |
13 | - Public Projects | |
9 | + %h1.title= title | |
14 | 10 | |
15 | 11 | .pull-right |
16 | 12 | = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in btn-new' | ... | ... |
app/views/layouts/public.html.haml
app/views/layouts/public_projects.html.haml
... | ... | @@ -2,8 +2,8 @@ |
2 | 2 | %html{ lang: "en"} |
3 | 3 | = render "layouts/head", title: @project.name_with_namespace |
4 | 4 | %body{class: "#{app_theme} application", :'data-page' => body_data_page} |
5 | - = render "layouts/public_head_panel" | |
6 | - %nav.main-nav.navbar-collapse.collapse | |
5 | + = render "layouts/public_head_panel", title: @project.name_with_namespace | |
6 | + %nav.main-nav | |
7 | 7 | .container= render 'layouts/nav/project' |
8 | 8 | .container |
9 | 9 | .content= yield | ... | ... |
features/admin/groups.feature
... | ... | @@ -2,7 +2,7 @@ Feature: Admin Groups |
2 | 2 | Background: |
3 | 3 | Given I sign in as an admin |
4 | 4 | And I have group with projects |
5 | - And Create gitlab user "John" | |
5 | + And Create user "John Doe" | |
6 | 6 | And I visit admin groups page |
7 | 7 | |
8 | 8 | Scenario: See group list |
... | ... | @@ -17,5 +17,5 @@ Feature: Admin Groups |
17 | 17 | @javascript |
18 | 18 | Scenario: Add user into projects in group |
19 | 19 | When I visit admin group page |
20 | - When I select user "John" from user list as "Reporter" | |
21 | - Then I should see "John" in team list in every project as "Reporter" | |
20 | + When I select user "John Doe" from user list as "Reporter" | |
21 | + Then I should see "John Doe" in team list in every project as "Reporter" | ... | ... |
features/group/group.feature
... | ... | @@ -21,10 +21,10 @@ Feature: Groups |
21 | 21 | |
22 | 22 | @javascript |
23 | 23 | Scenario: I should add user to projects in Group |
24 | - Given I have new user "John" | |
24 | + Given Create user "John Doe" | |
25 | 25 | When I visit group members page |
26 | - And I select user "John" from list with role "Reporter" | |
27 | - Then I should see user "John" in team list | |
26 | + And I select user "John Doe" from list with role "Reporter" | |
27 | + Then I should see user "John Doe" in team list | |
28 | 28 | |
29 | 29 | Scenario: I should see edit group page |
30 | 30 | When I visit group settings page | ... | ... |
features/steps/admin/admin_groups.rb
1 | 1 | class AdminGroups < Spinach::FeatureSteps |
2 | 2 | include SharedAuthentication |
3 | 3 | include SharedPaths |
4 | + include SharedUser | |
4 | 5 | include SharedActiveTab |
5 | 6 | include Select2Helper |
6 | 7 | |
... | ... | @@ -20,10 +21,6 @@ class AdminGroups < Spinach::FeatureSteps |
20 | 21 | @project.team << [current_user, :master] |
21 | 22 | end |
22 | 23 | |
23 | - And 'Create gitlab user "John"' do | |
24 | - create(:user, name: "John") | |
25 | - end | |
26 | - | |
27 | 24 | And 'submit form with new group info' do |
28 | 25 | fill_in 'group_name', with: 'gitlab' |
29 | 26 | fill_in 'group_description', with: 'Group description' |
... | ... | @@ -39,8 +36,8 @@ class AdminGroups < Spinach::FeatureSteps |
39 | 36 | current_path.should == admin_group_path(Group.last) |
40 | 37 | end |
41 | 38 | |
42 | - When 'I select user "John" from user list as "Reporter"' do | |
43 | - user = User.find_by(name: "John") | |
39 | + When 'I select user "John Doe" from user list as "Reporter"' do | |
40 | + user = User.find_by(name: "John Doe") | |
44 | 41 | select2(user.id, from: "#user_ids", multiple: true) |
45 | 42 | within "#new_team_member" do |
46 | 43 | select "Reporter", from: "group_access" |
... | ... | @@ -48,9 +45,9 @@ class AdminGroups < Spinach::FeatureSteps |
48 | 45 | click_button "Add users into group" |
49 | 46 | end |
50 | 47 | |
51 | - Then 'I should see "John" in team list in every project as "Reporter"' do | |
48 | + Then 'I should see "John Doe" in team list in every project as "Reporter"' do | |
52 | 49 | within ".group-users-list" do |
53 | - page.should have_content "John" | |
50 | + page.should have_content "John Doe" | |
54 | 51 | page.should have_content "Reporter" |
55 | 52 | end |
56 | 53 | end | ... | ... |
features/steps/group/group.rb
1 | 1 | class Groups < Spinach::FeatureSteps |
2 | 2 | include SharedAuthentication |
3 | 3 | include SharedPaths |
4 | + include SharedUser | |
4 | 5 | include Select2Helper |
5 | 6 | |
6 | 7 | Then 'I should see projects list' do |
... | ... | @@ -34,12 +35,8 @@ class Groups < Spinach::FeatureSteps |
34 | 35 | end |
35 | 36 | end |
36 | 37 | |
37 | - Given 'I have new user "John"' do | |
38 | - create(:user, name: "John") | |
39 | - end | |
40 | - | |
41 | - And 'I select user "John" from list with role "Reporter"' do | |
42 | - user = User.find_by(name: "John") | |
38 | + And 'I select user "John Doe" from list with role "Reporter"' do | |
39 | + user = User.find_by(name: "John Doe") | |
43 | 40 | within ".users-group-form" do |
44 | 41 | select2(user.id, from: "#user_ids", multiple: true) |
45 | 42 | select "Reporter", from: "group_access" |
... | ... | @@ -47,9 +44,9 @@ class Groups < Spinach::FeatureSteps |
47 | 44 | click_button "Add users into group" |
48 | 45 | end |
49 | 46 | |
50 | - Then 'I should see user "John" in team list' do | |
47 | + Then 'I should see user "John Doe" in team list' do | |
51 | 48 | projects_with_access = find(".ui-box .well-list") |
52 | - projects_with_access.should have_content("John") | |
49 | + projects_with_access.should have_content("John Doe") | |
53 | 50 | end |
54 | 51 | |
55 | 52 | Given 'project from group has issues assigned to me' do | ... | ... |
features/steps/public/projects_feature.rb
... | ... | @@ -3,12 +3,8 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps |
3 | 3 | include SharedPaths |
4 | 4 | include SharedProject |
5 | 5 | |
6 | - step 'I should see project "Community"' do | |
7 | - page.should have_content "Community" | |
8 | - end | |
9 | - | |
10 | - step 'I should not see project "Enterprise"' do | |
11 | - page.should_not have_content "Enterprise" | |
6 | + step 'public empty project "Empty Public Project"' do | |
7 | + create :empty_project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC | |
12 | 8 | end |
13 | 9 | |
14 | 10 | step 'I should see project "Empty Public Project"' do |
... | ... | @@ -24,14 +20,6 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps |
24 | 20 | page.should have_content 'README.md' |
25 | 21 | end |
26 | 22 | |
27 | - step 'public project "Community"' do | |
28 | - create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC | |
29 | - end | |
30 | - | |
31 | - step 'public empty project "Empty Public Project"' do | |
32 | - create :empty_project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC | |
33 | - end | |
34 | - | |
35 | 23 | step 'I visit empty project page' do |
36 | 24 | project = Project.find_by(name: 'Empty Public Project') |
37 | 25 | visit project_path(project) |
... | ... | @@ -60,10 +48,6 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps |
60 | 48 | end |
61 | 49 | end |
62 | 50 | |
63 | - step 'private project "Enterprise"' do | |
64 | - create :project, name: 'Enterprise' | |
65 | - end | |
66 | - | |
67 | 51 | step 'I visit project "Enterprise" page' do |
68 | 52 | project = Project.find_by(name: 'Enterprise') |
69 | 53 | visit project_path(project) |
... | ... | @@ -75,18 +59,6 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps |
75 | 59 | end |
76 | 60 | end |
77 | 61 | |
78 | - step 'internal project "Internal"' do | |
79 | - create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL | |
80 | - end | |
81 | - | |
82 | - step 'I should see project "Internal"' do | |
83 | - page.should have_content "Internal" | |
84 | - end | |
85 | - | |
86 | - step 'I should not see project "Internal"' do | |
87 | - page.should_not have_content "Internal" | |
88 | - end | |
89 | - | |
90 | 62 | step 'I visit project "Internal" page' do |
91 | 63 | project = Project.find_by(name: 'Internal') |
92 | 64 | visit project_path(project) | ... | ... |
features/steps/shared/paths.rb
... | ... | @@ -6,6 +6,14 @@ module SharedPaths |
6 | 6 | end |
7 | 7 | |
8 | 8 | # ---------------------------------------- |
9 | + # User | |
10 | + # ---------------------------------------- | |
11 | + | |
12 | + step 'I visit user "John Doe" page' do | |
13 | + visit user_path("john_doe") | |
14 | + end | |
15 | + | |
16 | + # ---------------------------------------- | |
9 | 17 | # Group |
10 | 18 | # ---------------------------------------- |
11 | 19 | ... | ... |
features/steps/shared/project.rb
... | ... | @@ -65,4 +65,68 @@ module SharedProject |
65 | 65 | def current_project |
66 | 66 | @project ||= Project.first |
67 | 67 | end |
68 | + | |
69 | + # ---------------------------------------- | |
70 | + # Visibility level | |
71 | + # ---------------------------------------- | |
72 | + | |
73 | + step 'private project "Enterprise"' do | |
74 | + create :project, name: 'Enterprise' | |
75 | + end | |
76 | + | |
77 | + step 'I should see project "Enterprise"' do | |
78 | + page.should have_content "Enterprise" | |
79 | + end | |
80 | + | |
81 | + step 'I should not see project "Enterprise"' do | |
82 | + page.should_not have_content "Enterprise" | |
83 | + end | |
84 | + | |
85 | + step 'internal project "Internal"' do | |
86 | + create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL | |
87 | + end | |
88 | + | |
89 | + step 'I should see project "Internal"' do | |
90 | + page.should have_content "Internal" | |
91 | + end | |
92 | + | |
93 | + step 'I should not see project "Internal"' do | |
94 | + page.should_not have_content "Internal" | |
95 | + end | |
96 | + | |
97 | + step 'public project "Community"' do | |
98 | + create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC | |
99 | + end | |
100 | + | |
101 | + step 'I should see project "Community"' do | |
102 | + page.should have_content "Community" | |
103 | + end | |
104 | + | |
105 | + step 'I should not see project "Community"' do | |
106 | + page.should_not have_content "Community" | |
107 | + end | |
108 | + | |
109 | + step '"John Doe" is authorized to private project "Enterprise"' do | |
110 | + user = User.find_by(name: "John Doe") | |
111 | + user ||= create(:user, name: "John Doe", username: "john_doe") | |
112 | + project = Project.find_by(name: "Enterprise") | |
113 | + project ||= create(:project, name: "Enterprise", namespace: user.namespace) | |
114 | + project.team << [user, :master] | |
115 | + end | |
116 | + | |
117 | + step '"John Doe" is authorized to internal project "Internal"' do | |
118 | + user = User.find_by(name: "John Doe") | |
119 | + user ||= create(:user, name: "John Doe", username: "john_doe") | |
120 | + project = Project.find_by(name: "Internal") | |
121 | + project ||= create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL | |
122 | + project.team << [user, :master] | |
123 | + end | |
124 | + | |
125 | + step '"John Doe" is authorized to public project "Community"' do | |
126 | + user = User.find_by(name: "John Doe") | |
127 | + user ||= create(:user, name: "John Doe", username: "john_doe") | |
128 | + project = Project.find_by(name: "Community") | |
129 | + project ||= create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC | |
130 | + project.team << [user, :master] | |
131 | + end | |
68 | 132 | end | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +class Spinach::Features::User < Spinach::FeatureSteps | |
2 | + include SharedAuthentication | |
3 | + include SharedPaths | |
4 | + include SharedUser | |
5 | + include SharedProject | |
6 | + | |
7 | + step 'I should see user "John Doe" page' do | |
8 | + expect(page.title).to match(/^\s*John Doe/) | |
9 | + end | |
10 | +end | ... | ... |
... | ... | @@ -0,0 +1,69 @@ |
1 | +Feature: User | |
2 | + Background: | |
3 | + Given Create user "John Doe" | |
4 | + And "John Doe" is authorized to private project "Enterprise" | |
5 | + | |
6 | + # Signed out | |
7 | + | |
8 | + Scenario: I visit user "John Doe" page while not signed in when he is authorized to a public project | |
9 | + Given "John Doe" is authorized to internal project "Internal" | |
10 | + And "John Doe" is authorized to public project "Community" | |
11 | + When I visit user "John Doe" page | |
12 | + Then I should see user "John Doe" page | |
13 | + And I should not see project "Enterprise" | |
14 | + And I should not see project "Internal" | |
15 | + And I should see project "Community" | |
16 | + | |
17 | + Scenario: I visit user "John Doe" page while not signed in when he is not authorized to a public project | |
18 | + Given "John Doe" is authorized to internal project "Internal" | |
19 | + When I visit user "John Doe" page | |
20 | + Then I should be redirected to sign in page | |
21 | + | |
22 | + # Signed in as someone else | |
23 | + | |
24 | + Scenario: I visit user "John Doe" page while signed in as someone else when he is authorized to a public project | |
25 | + Given "John Doe" is authorized to public project "Community" | |
26 | + And "John Doe" is authorized to internal project "Internal" | |
27 | + And I sign in as a user | |
28 | + When I visit user "John Doe" page | |
29 | + Then I should see user "John Doe" page | |
30 | + And I should not see project "Enterprise" | |
31 | + And I should see project "Internal" | |
32 | + And I should see project "Community" | |
33 | + | |
34 | + Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a public project | |
35 | + Given "John Doe" is authorized to internal project "Internal" | |
36 | + And I sign in as a user | |
37 | + When I visit user "John Doe" page | |
38 | + Then I should see user "John Doe" page | |
39 | + And I should not see project "Enterprise" | |
40 | + And I should see project "Internal" | |
41 | + And I should not see project "Community" | |
42 | + | |
43 | + Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a project I can see | |
44 | + Given I sign in as a user | |
45 | + When I visit user "John Doe" page | |
46 | + Then I should see user "John Doe" page | |
47 | + And I should not see project "Enterprise" | |
48 | + And I should not see project "Internal" | |
49 | + And I should not see project "Community" | |
50 | + | |
51 | + # Signed in as the user himself | |
52 | + | |
53 | + Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has a public project | |
54 | + Given "John Doe" is authorized to internal project "Internal" | |
55 | + And "John Doe" is authorized to public project "Community" | |
56 | + And I sign in as "John Doe" | |
57 | + When I visit user "John Doe" page | |
58 | + Then I should see user "John Doe" page | |
59 | + And I should see project "Enterprise" | |
60 | + And I should see project "Internal" | |
61 | + And I should see project "Community" | |
62 | + | |
63 | + Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has no public project | |
64 | + Given I sign in as "John Doe" | |
65 | + When I visit user "John Doe" page | |
66 | + Then I should see user "John Doe" page | |
67 | + And I should see project "Enterprise" | |
68 | + And I should not see project "Internal" | |
69 | + And I should not see project "Community" | ... | ... |