Commit 232d61d59808e6f0c731d135d728800c4b13ae27
1 parent
c7c1a97c
Exists in
master
and in
4 other branches
Refactor project creation. Added logout link to profile page
Showing
19 changed files
with
126 additions
and
116 deletions
Show diff stats
app/assets/stylesheets/sections/projects.scss
app/contexts/project_update_context.rb
@@ -1,24 +0,0 @@ | @@ -1,24 +0,0 @@ | ||
1 | -class ProjectUpdateContext < BaseContext | ||
2 | - def execute(role = :default) | ||
3 | - namespace_id = params[:project].delete(:namespace_id) | ||
4 | - params[:project].delete(:public) unless can?(current_user, :change_public_mode, project) | ||
5 | - | ||
6 | - allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin | ||
7 | - | ||
8 | - if allowed_transfer && namespace_id.present? | ||
9 | - if namespace_id == Namespace.global_id | ||
10 | - if project.namespace.present? | ||
11 | - # Transfer to global namespace from anyone | ||
12 | - project.transfer(nil) | ||
13 | - end | ||
14 | - elsif namespace_id.to_i != project.namespace_id | ||
15 | - # Transfer to someone namespace | ||
16 | - namespace = Namespace.find(namespace_id) | ||
17 | - project.transfer(namespace) | ||
18 | - end | ||
19 | - end | ||
20 | - | ||
21 | - project.update_attributes(params[:project], as: role) | ||
22 | - end | ||
23 | -end | ||
24 | - |
@@ -0,0 +1,64 @@ | @@ -0,0 +1,64 @@ | ||
1 | +module Projects | ||
2 | + class CreateContext < BaseContext | ||
3 | + def execute | ||
4 | + # get namespace id | ||
5 | + namespace_id = params[:project].delete(:namespace_id) | ||
6 | + | ||
7 | + @project = Project.new(params[:project]) | ||
8 | + | ||
9 | + # Parametrize path for project | ||
10 | + # | ||
11 | + # Ex. | ||
12 | + # 'GitLab HQ'.parameterize => "gitlab-hq" | ||
13 | + # | ||
14 | + @project.path = @project.name.dup.parameterize | ||
15 | + | ||
16 | + | ||
17 | + if namespace_id | ||
18 | + # Find matching namespace and check if it allowed | ||
19 | + # for current user if namespace_id passed. | ||
20 | + if allowed_namespace?(current_user, namespace_id) | ||
21 | + @project.namespace_id = namespace_id unless namespace_id == Namespace.global_id | ||
22 | + else | ||
23 | + deny_namespace | ||
24 | + return @project | ||
25 | + end | ||
26 | + else | ||
27 | + # Set current user namespace if namespace_id is nil | ||
28 | + @project.namespace_id = current_user.id | ||
29 | + end | ||
30 | + | ||
31 | + Project.transaction do | ||
32 | + @project.creator = current_user | ||
33 | + @project.save! | ||
34 | + | ||
35 | + # Add user as project master | ||
36 | + @project.users_projects.create!(project_access: UsersProject::MASTER, user: current_user) | ||
37 | + | ||
38 | + # when project saved no team member exist so | ||
39 | + # project repository should be updated after first user add | ||
40 | + @project.update_repository | ||
41 | + end | ||
42 | + | ||
43 | + @project | ||
44 | + rescue => ex | ||
45 | + @project.errors.add(:base, "Can't save project. Please try again later") | ||
46 | + @project | ||
47 | + end | ||
48 | + | ||
49 | + protected | ||
50 | + | ||
51 | + def deny_namespace | ||
52 | + @project.errors.add(:namespace, "is not valid") | ||
53 | + end | ||
54 | + | ||
55 | + def allowed_namespace?(user, namespace_id) | ||
56 | + if namespace_id == Namespace.global_id | ||
57 | + return user.admin | ||
58 | + else | ||
59 | + namespace = Namespace.find_by_id(namespace_id) | ||
60 | + current_user.can?(:manage_namespace, namespace) | ||
61 | + end | ||
62 | + end | ||
63 | + end | ||
64 | +end |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +module Projects | ||
2 | + class UpdateContext < BaseContext | ||
3 | + def execute(role = :default) | ||
4 | + namespace_id = params[:project].delete(:namespace_id) | ||
5 | + params[:project].delete(:public) unless can?(current_user, :change_public_mode, project) | ||
6 | + | ||
7 | + allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin | ||
8 | + | ||
9 | + if allowed_transfer && namespace_id.present? | ||
10 | + if namespace_id == Namespace.global_id | ||
11 | + if project.namespace.present? | ||
12 | + # Transfer to global namespace from anyone | ||
13 | + project.transfer(nil) | ||
14 | + end | ||
15 | + elsif namespace_id.to_i != project.namespace_id | ||
16 | + # Transfer to someone namespace | ||
17 | + namespace = Namespace.find(namespace_id) | ||
18 | + project.transfer(namespace) | ||
19 | + end | ||
20 | + end | ||
21 | + | ||
22 | + project.update_attributes(params[:project], as: role) | ||
23 | + end | ||
24 | + end | ||
25 | +end |
app/controllers/admin/projects_controller.rb
@@ -29,7 +29,7 @@ class Admin::ProjectsController < AdminController | @@ -29,7 +29,7 @@ class Admin::ProjectsController < AdminController | ||
29 | end | 29 | end |
30 | 30 | ||
31 | def update | 31 | def update |
32 | - status = ProjectUpdateContext.new(project, current_user, params).execute(:admin) | 32 | + status = Projects::UpdateContext.new(project, current_user, params).execute(:admin) |
33 | 33 | ||
34 | if status | 34 | if status |
35 | redirect_to [:admin, @project], notice: 'Project was successfully updated.' | 35 | redirect_to [:admin, @project], notice: 'Project was successfully updated.' |
app/controllers/projects_controller.rb
@@ -19,7 +19,7 @@ class ProjectsController < ProjectResourceController | @@ -19,7 +19,7 @@ class ProjectsController < ProjectResourceController | ||
19 | end | 19 | end |
20 | 20 | ||
21 | def create | 21 | def create |
22 | - @project = Project.create_by_user(params[:project], current_user) | 22 | + @project = Projects::CreateContext.new(nil, current_user, params).execute |
23 | 23 | ||
24 | respond_to do |format| | 24 | respond_to do |format| |
25 | flash[:notice] = 'Project was successfully created.' if @project.saved? | 25 | flash[:notice] = 'Project was successfully created.' if @project.saved? |
@@ -35,7 +35,7 @@ class ProjectsController < ProjectResourceController | @@ -35,7 +35,7 @@ class ProjectsController < ProjectResourceController | ||
35 | end | 35 | end |
36 | 36 | ||
37 | def update | 37 | def update |
38 | - status = ProjectUpdateContext.new(project, current_user, params).execute | 38 | + status = Projects::UpdateContext.new(project, current_user, params).execute |
39 | 39 | ||
40 | respond_to do |format| | 40 | respond_to do |format| |
41 | if status | 41 | if status |
app/helpers/namespaces_helper.rb
1 | module NamespacesHelper | 1 | module NamespacesHelper |
2 | def namespaces_options(selected = :current_user, scope = :default) | 2 | def namespaces_options(selected = :current_user, scope = :default) |
3 | - groups = current_user.owned_groups.select {|n| n.type == 'Group'} | 3 | + if current_user.admin |
4 | + groups = Group.all | ||
5 | + users = Namespace.root | ||
6 | + else | ||
7 | + groups = current_user.owned_groups.select {|n| n.type == 'Group'} | ||
8 | + users = current_user.namespaces.reject {|n| n.type == 'Group'} | ||
9 | + end | ||
4 | 10 | ||
5 | - users = if scope == :all | ||
6 | - Namespace.root | ||
7 | - else | ||
8 | - current_user.namespaces.reject {|n| n.type == 'Group'} | ||
9 | - end | ||
10 | 11 | ||
11 | global_opts = ["Global", [['/', Namespace.global_id]] ] | 12 | global_opts = ["Global", [['/', Namespace.global_id]] ] |
12 | group_opts = ["Groups", groups.map {|g| [g.human_name, g.id]} ] | 13 | group_opts = ["Groups", groups.map {|g| [g.human_name, g.id]} ] |
app/models/ability.rb
@@ -7,7 +7,7 @@ class Ability | @@ -7,7 +7,7 @@ class Ability | ||
7 | when "Note" then note_abilities(object, subject) | 7 | when "Note" then note_abilities(object, subject) |
8 | when "Snippet" then snippet_abilities(object, subject) | 8 | when "Snippet" then snippet_abilities(object, subject) |
9 | when "MergeRequest" then merge_request_abilities(object, subject) | 9 | when "MergeRequest" then merge_request_abilities(object, subject) |
10 | - when "Group" then group_abilities(object, subject) | 10 | + when "Group", "Namespace" then group_abilities(object, subject) |
11 | else [] | 11 | else [] |
12 | end | 12 | end |
13 | end | 13 | end |
@@ -102,7 +102,8 @@ class Ability | @@ -102,7 +102,8 @@ class Ability | ||
102 | # Only group owner and administrators can manage group | 102 | # Only group owner and administrators can manage group |
103 | if group.owner == user || user.admin? | 103 | if group.owner == user || user.admin? |
104 | rules << [ | 104 | rules << [ |
105 | - :manage_group | 105 | + :manage_group, |
106 | + :manage_namespace | ||
106 | ] | 107 | ] |
107 | end | 108 | end |
108 | 109 |
app/models/project.rb
@@ -116,55 +116,6 @@ class Project < ActiveRecord::Base | @@ -116,55 +116,6 @@ class Project < ActiveRecord::Base | ||
116 | end | 116 | end |
117 | end | 117 | end |
118 | 118 | ||
119 | - def create_by_user(params, user) | ||
120 | - namespace_id = params.delete(:namespace_id) | ||
121 | - | ||
122 | - project = Project.new params | ||
123 | - | ||
124 | - Project.transaction do | ||
125 | - | ||
126 | - # Parametrize path for project | ||
127 | - # | ||
128 | - # Ex. | ||
129 | - # 'GitLab HQ'.parameterize => "gitlab-hq" | ||
130 | - # | ||
131 | - project.path = project.name.dup.parameterize | ||
132 | - | ||
133 | - project.creator = user | ||
134 | - | ||
135 | - # Apply namespace if user has access to it | ||
136 | - # else fallback to user namespace | ||
137 | - if namespace_id != Namespace.global_id | ||
138 | - project.namespace_id = user.namespace_id | ||
139 | - | ||
140 | - if namespace_id | ||
141 | - group = Group.find_by_id(namespace_id) | ||
142 | - if user.can? :manage_group, group | ||
143 | - project.namespace_id = namespace_id | ||
144 | - end | ||
145 | - end | ||
146 | - end | ||
147 | - | ||
148 | - project.save! | ||
149 | - | ||
150 | - # Add user as project master | ||
151 | - project.users_projects.create!(project_access: UsersProject::MASTER, user: user) | ||
152 | - | ||
153 | - # when project saved no team member exist so | ||
154 | - # project repository should be updated after first user add | ||
155 | - project.update_repository | ||
156 | - end | ||
157 | - | ||
158 | - project | ||
159 | - rescue Gitlab::Gitolite::AccessDenied => ex | ||
160 | - project.error_code = :gitolite | ||
161 | - project | ||
162 | - rescue => ex | ||
163 | - project.error_code = :db | ||
164 | - project.errors.add(:base, "Can't save project. Please try again later") | ||
165 | - project | ||
166 | - end | ||
167 | - | ||
168 | def access_options | 119 | def access_options |
169 | UsersProject.access_roles | 120 | UsersProject.access_roles |
170 | end | 121 | end |
app/models/user.rb
@@ -152,11 +152,8 @@ class User < ActiveRecord::Base | @@ -152,11 +152,8 @@ class User < ActiveRecord::Base | ||
152 | namespaces << self.namespace if self.namespace | 152 | namespaces << self.namespace if self.namespace |
153 | 153 | ||
154 | # Add groups you can manage | 154 | # Add groups you can manage |
155 | - namespaces += if admin | ||
156 | - Group.all | ||
157 | - else | ||
158 | - groups.all | ||
159 | - end | 155 | + namespaces += groups.all |
156 | + | ||
160 | namespaces | 157 | namespaces |
161 | end | 158 | end |
162 | 159 | ||
@@ -234,6 +231,10 @@ class User < ActiveRecord::Base | @@ -234,6 +231,10 @@ class User < ActiveRecord::Base | ||
234 | end | 231 | end |
235 | end | 232 | end |
236 | 233 | ||
234 | + def can_select_namespace? | ||
235 | + several_namespaces? || admin | ||
236 | + end | ||
237 | + | ||
237 | def can? action, subject | 238 | def can? action, subject |
238 | abilities.allowed?(self, action, subject) | 239 | abilities.allowed?(self, action, subject) |
239 | end | 240 | end |
app/views/dashboard/_sidebar.html.haml
@@ -9,6 +9,6 @@ | @@ -9,6 +9,6 @@ | ||
9 | 9 | ||
10 | %hr | 10 | %hr |
11 | .gitlab-promo | 11 | .gitlab-promo |
12 | - = link_to "Homepage", "http://gitlabhq.com" | ||
13 | - = link_to "Blog", "http://blog.gitlabhq.com" | 12 | + = link_to "Homepage", "http://gitlab.org" |
13 | + = link_to "Blog", "http://blog.gitlab.org" | ||
14 | = link_to "@gitlabhq", "https://twitter.com/gitlabhq" | 14 | = link_to "@gitlabhq", "https://twitter.com/gitlabhq" |
app/views/profiles/show.html.haml
@@ -6,6 +6,11 @@ | @@ -6,6 +6,11 @@ | ||
6 | %small | 6 | %small |
7 | = @user.email | 7 | = @user.email |
8 | 8 | ||
9 | + .right | ||
10 | + = link_to destroy_user_session_path, class: "logout", method: :delete do | ||
11 | + %small | ||
12 | + %i.icon-signout | ||
13 | + Logout | ||
9 | %hr | 14 | %hr |
10 | 15 | ||
11 | = form_for @user, url: profile_path, method: :put, html: { class: "edit_user form-horizontal" } do |f| | 16 | = form_for @user, url: profile_path, method: :put, html: { class: "edit_user form-horizontal" } do |f| |
app/views/projects/_form.html.haml
@@ -9,19 +9,11 @@ | @@ -9,19 +9,11 @@ | ||
9 | Project name is | 9 | Project name is |
10 | .input | 10 | .input |
11 | = f.text_field :name, placeholder: "Example Project", class: "xxlarge" | 11 | = f.text_field :name, placeholder: "Example Project", class: "xxlarge" |
12 | - %fieldset | ||
13 | - %legend Advanced settings: | ||
14 | - .control-group | ||
15 | - = f.label :path do | ||
16 | - Repository | ||
17 | - .controls | ||
18 | - = text_field_tag :ppath, @repository.path_to_repo, class: "xxlarge", readonly: true | ||
19 | - | 12 | + - unless @repository.heads.empty? |
13 | + .clearfix | ||
14 | + = f.label :default_branch, "Default Branch" | ||
15 | + .input= f.select(:default_branch, @repository.heads.map(&:name), {}, style: "width:210px;") | ||
20 | 16 | ||
21 | - - unless @repository.heads.empty? | ||
22 | - .clearfix | ||
23 | - = f.label :default_branch, "Default Branch" | ||
24 | - .input= f.select(:default_branch, @repository.heads.map(&:name), {}, style: "width:210px;") | ||
25 | 17 | ||
26 | %fieldset.features | 18 | %fieldset.features |
27 | %legend Features: | 19 | %legend Features: |
@@ -87,4 +79,4 @@ | @@ -87,4 +79,4 @@ | ||
87 | - unless @project.new_record? | 79 | - unless @project.new_record? |
88 | - if can?(current_user, :remove_project, @project) | 80 | - if can?(current_user, :remove_project, @project) |
89 | .right | 81 | .right |
90 | - = link_to 'Remove', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn danger" | 82 | + = link_to 'Remove Project', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn danger" |
app/views/projects/_new_form.html.haml
@@ -9,10 +9,10 @@ | @@ -9,10 +9,10 @@ | ||
9 | = f.text_field :name, placeholder: "Example Project", class: "xxlarge" | 9 | = f.text_field :name, placeholder: "Example Project", class: "xxlarge" |
10 | = f.submit 'Create project', class: "btn success project-submit" | 10 | = f.submit 'Create project', class: "btn success project-submit" |
11 | 11 | ||
12 | - - if current_user.several_namespaces? | 12 | + - if current_user.can_select_namespace? |
13 | .clearfix | 13 | .clearfix |
14 | = f.label :namespace_id do | 14 | = f.label :namespace_id do |
15 | - %span.cgray Namespace | 15 | + %span Namespace |
16 | .input | 16 | .input |
17 | = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'chosen'} | 17 | = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'chosen'} |
18 | %hr | 18 | %hr |
app/views/projects/create.js.haml
@@ -2,11 +2,9 @@ | @@ -2,11 +2,9 @@ | ||
2 | :plain | 2 | :plain |
3 | location.href = "#{project_path(@project)}"; | 3 | location.href = "#{project_path(@project)}"; |
4 | - else | 4 | - else |
5 | - - if @project.git_error? | ||
6 | - location.href = "#{errors_githost_path}"; | ||
7 | - -else | ||
8 | :plain | 5 | :plain |
9 | $('.project_new_holder').show(); | 6 | $('.project_new_holder').show(); |
10 | $("#new_project").replaceWith("#{escape_javascript(render('new_form'))}"); | 7 | $("#new_project").replaceWith("#{escape_javascript(render('new_form'))}"); |
11 | $('.save-project-loader').hide(); | 8 | $('.save-project-loader').hide(); |
12 | new Projects(); | 9 | new Projects(); |
10 | + $('select.chosen').chosen() |
features/project/project.feature
features/steps/project/project.rb
features/steps/shared/project.rb
@@ -47,7 +47,6 @@ module SharedProject | @@ -47,7 +47,6 @@ module SharedProject | ||
47 | Then 'I should see project settings' do | 47 | Then 'I should see project settings' do |
48 | current_path.should == edit_project_path(@project) | 48 | current_path.should == edit_project_path(@project) |
49 | page.should have_content("Project name is") | 49 | page.should have_content("Project name is") |
50 | - page.should have_content("Advanced settings:") | ||
51 | page.should have_content("Features:") | 50 | page.should have_content("Features:") |
52 | end | 51 | end |
53 | 52 |
lib/api/projects.rb
@@ -43,7 +43,7 @@ module Gitlab | @@ -43,7 +43,7 @@ module Gitlab | ||
43 | :wall_enabled, | 43 | :wall_enabled, |
44 | :merge_requests_enabled, | 44 | :merge_requests_enabled, |
45 | :wiki_enabled] | 45 | :wiki_enabled] |
46 | - @project = Project.create_by_user(attrs, current_user) | 46 | + @project = Projects::CreateContext.new(nil, attrs, current_user).execute |
47 | if @project.saved? | 47 | if @project.saved? |
48 | present @project, with: Entities::Project | 48 | present @project, with: Entities::Project |
49 | else | 49 | else |