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 | -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 @@ |
| 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 @@ |
| 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 | 29 | end |
| 30 | 30 | |
| 31 | 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 | 34 | if status |
| 35 | 35 | redirect_to [:admin, @project], notice: 'Project was successfully updated.' | ... | ... |
app/controllers/projects_controller.rb
| ... | ... | @@ -19,7 +19,7 @@ class ProjectsController < ProjectResourceController |
| 19 | 19 | end |
| 20 | 20 | |
| 21 | 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 | 24 | respond_to do |format| |
| 25 | 25 | flash[:notice] = 'Project was successfully created.' if @project.saved? |
| ... | ... | @@ -35,7 +35,7 @@ class ProjectsController < ProjectResourceController |
| 35 | 35 | end |
| 36 | 36 | |
| 37 | 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 | 40 | respond_to do |format| |
| 41 | 41 | if status | ... | ... |
app/helpers/namespaces_helper.rb
| 1 | 1 | module NamespacesHelper |
| 2 | 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 | 12 | global_opts = ["Global", [['/', Namespace.global_id]] ] |
| 12 | 13 | group_opts = ["Groups", groups.map {|g| [g.human_name, g.id]} ] | ... | ... |
app/models/ability.rb
| ... | ... | @@ -7,7 +7,7 @@ class Ability |
| 7 | 7 | when "Note" then note_abilities(object, subject) |
| 8 | 8 | when "Snippet" then snippet_abilities(object, subject) |
| 9 | 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 | 11 | else [] |
| 12 | 12 | end |
| 13 | 13 | end |
| ... | ... | @@ -102,7 +102,8 @@ class Ability |
| 102 | 102 | # Only group owner and administrators can manage group |
| 103 | 103 | if group.owner == user || user.admin? |
| 104 | 104 | rules << [ |
| 105 | - :manage_group | |
| 105 | + :manage_group, | |
| 106 | + :manage_namespace | |
| 106 | 107 | ] |
| 107 | 108 | end |
| 108 | 109 | ... | ... |
app/models/project.rb
| ... | ... | @@ -116,55 +116,6 @@ class Project < ActiveRecord::Base |
| 116 | 116 | end |
| 117 | 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 | 119 | def access_options |
| 169 | 120 | UsersProject.access_roles |
| 170 | 121 | end | ... | ... |
app/models/user.rb
| ... | ... | @@ -152,11 +152,8 @@ class User < ActiveRecord::Base |
| 152 | 152 | namespaces << self.namespace if self.namespace |
| 153 | 153 | |
| 154 | 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 | 157 | namespaces |
| 161 | 158 | end |
| 162 | 159 | |
| ... | ... | @@ -234,6 +231,10 @@ class User < ActiveRecord::Base |
| 234 | 231 | end |
| 235 | 232 | end |
| 236 | 233 | |
| 234 | + def can_select_namespace? | |
| 235 | + several_namespaces? || admin | |
| 236 | + end | |
| 237 | + | |
| 237 | 238 | def can? action, subject |
| 238 | 239 | abilities.allowed?(self, action, subject) |
| 239 | 240 | end | ... | ... |
app/views/dashboard/_sidebar.html.haml
| ... | ... | @@ -9,6 +9,6 @@ |
| 9 | 9 | |
| 10 | 10 | %hr |
| 11 | 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 | 14 | = link_to "@gitlabhq", "https://twitter.com/gitlabhq" | ... | ... |
app/views/profiles/show.html.haml
| ... | ... | @@ -6,6 +6,11 @@ |
| 6 | 6 | %small |
| 7 | 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 | 14 | %hr |
| 10 | 15 | |
| 11 | 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 | 9 | Project name is |
| 10 | 10 | .input |
| 11 | 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 | 18 | %fieldset.features |
| 27 | 19 | %legend Features: |
| ... | ... | @@ -87,4 +79,4 @@ |
| 87 | 79 | - unless @project.new_record? |
| 88 | 80 | - if can?(current_user, :remove_project, @project) |
| 89 | 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 | 9 | = f.text_field :name, placeholder: "Example Project", class: "xxlarge" |
| 10 | 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 | 13 | .clearfix |
| 14 | 14 | = f.label :namespace_id do |
| 15 | - %span.cgray Namespace | |
| 15 | + %span Namespace | |
| 16 | 16 | .input |
| 17 | 17 | = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'chosen'} |
| 18 | 18 | %hr | ... | ... |
app/views/projects/create.js.haml
| ... | ... | @@ -2,11 +2,9 @@ |
| 2 | 2 | :plain |
| 3 | 3 | location.href = "#{project_path(@project)}"; |
| 4 | 4 | - else |
| 5 | - - if @project.git_error? | |
| 6 | - location.href = "#{errors_githost_path}"; | |
| 7 | - -else | |
| 8 | 5 | :plain |
| 9 | 6 | $('.project_new_holder').show(); |
| 10 | 7 | $("#new_project").replaceWith("#{escape_javascript(render('new_form'))}"); |
| 11 | 8 | $('.save-project-loader').hide(); |
| 12 | 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 | 47 | Then 'I should see project settings' do |
| 48 | 48 | current_path.should == edit_project_path(@project) |
| 49 | 49 | page.should have_content("Project name is") |
| 50 | - page.should have_content("Advanced settings:") | |
| 51 | 50 | page.should have_content("Features:") |
| 52 | 51 | end |
| 53 | 52 | ... | ... |
lib/api/projects.rb
| ... | ... | @@ -43,7 +43,7 @@ module Gitlab |
| 43 | 43 | :wall_enabled, |
| 44 | 44 | :merge_requests_enabled, |
| 45 | 45 | :wiki_enabled] |
| 46 | - @project = Project.create_by_user(attrs, current_user) | |
| 46 | + @project = Projects::CreateContext.new(nil, attrs, current_user).execute | |
| 47 | 47 | if @project.saved? |
| 48 | 48 | present @project, with: Entities::Project |
| 49 | 49 | else | ... | ... |