From 232d61d59808e6f0c731d135d728800c4b13ae27 Mon Sep 17 00:00:00 2001 From: GitLab Date: Thu, 17 Jan 2013 17:35:57 +0200 Subject: [PATCH] Refactor project creation. Added logout link to profile page --- app/assets/stylesheets/sections/projects.scss | 3 - app/contexts/project_update_context.rb | 24 ------- app/contexts/projects/create_context.rb | 64 +++++++++++++++++++ app/contexts/projects/update_context.rb | 25 ++++++++ app/controllers/admin/projects_controller.rb | 2 +- app/controllers/projects_controller.rb | 4 +- app/helpers/namespaces_helper.rb | 13 ++-- app/models/ability.rb | 5 +- app/models/project.rb | 49 -------------- app/models/user.rb | 11 ++-- app/views/dashboard/_sidebar.html.haml | 4 +- app/views/profiles/show.html.haml | 5 ++ app/views/projects/_form.html.haml | 18 ++---- app/views/projects/_new_form.html.haml | 4 +- app/views/projects/create.js.haml | 4 +- features/project/project.feature | 2 +- features/steps/project/project.rb | 2 +- features/steps/shared/project.rb | 1 - lib/api/projects.rb | 2 +- 19 files changed, 126 insertions(+), 116 deletions(-) delete mode 100644 app/contexts/project_update_context.rb create mode 100644 app/contexts/projects/create_context.rb create mode 100644 app/contexts/projects/update_context.rb diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index 072ade80ad3..4bdc56d2884 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -42,9 +42,6 @@ line-height: 20px; padding: 8px; } - label { - color: #888; - } .btn { padding: 6px 10px; margin-left: 10px; diff --git a/app/contexts/project_update_context.rb b/app/contexts/project_update_context.rb deleted file mode 100644 index f6d69e7b62d..00000000000 --- a/app/contexts/project_update_context.rb +++ /dev/null @@ -1,24 +0,0 @@ -class ProjectUpdateContext < BaseContext - def execute(role = :default) - namespace_id = params[:project].delete(:namespace_id) - params[:project].delete(:public) unless can?(current_user, :change_public_mode, project) - - allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin - - if allowed_transfer && namespace_id.present? - if namespace_id == Namespace.global_id - if project.namespace.present? - # Transfer to global namespace from anyone - project.transfer(nil) - end - elsif namespace_id.to_i != project.namespace_id - # Transfer to someone namespace - namespace = Namespace.find(namespace_id) - project.transfer(namespace) - end - end - - project.update_attributes(params[:project], as: role) - end -end - diff --git a/app/contexts/projects/create_context.rb b/app/contexts/projects/create_context.rb new file mode 100644 index 00000000000..5329443c5f7 --- /dev/null +++ b/app/contexts/projects/create_context.rb @@ -0,0 +1,64 @@ +module Projects + class CreateContext < BaseContext + def execute + # get namespace id + namespace_id = params[:project].delete(:namespace_id) + + @project = Project.new(params[:project]) + + # Parametrize path for project + # + # Ex. + # 'GitLab HQ'.parameterize => "gitlab-hq" + # + @project.path = @project.name.dup.parameterize + + + if namespace_id + # Find matching namespace and check if it allowed + # for current user if namespace_id passed. + if allowed_namespace?(current_user, namespace_id) + @project.namespace_id = namespace_id unless namespace_id == Namespace.global_id + else + deny_namespace + return @project + end + else + # Set current user namespace if namespace_id is nil + @project.namespace_id = current_user.id + end + + Project.transaction do + @project.creator = current_user + @project.save! + + # Add user as project master + @project.users_projects.create!(project_access: UsersProject::MASTER, user: current_user) + + # when project saved no team member exist so + # project repository should be updated after first user add + @project.update_repository + end + + @project + rescue => ex + @project.errors.add(:base, "Can't save project. Please try again later") + @project + end + + protected + + def deny_namespace + @project.errors.add(:namespace, "is not valid") + end + + def allowed_namespace?(user, namespace_id) + if namespace_id == Namespace.global_id + return user.admin + else + namespace = Namespace.find_by_id(namespace_id) + current_user.can?(:manage_namespace, namespace) + end + end + end +end diff --git a/app/contexts/projects/update_context.rb b/app/contexts/projects/update_context.rb new file mode 100644 index 00000000000..e5d09b7df7f --- /dev/null +++ b/app/contexts/projects/update_context.rb @@ -0,0 +1,25 @@ +module Projects + class UpdateContext < BaseContext + def execute(role = :default) + namespace_id = params[:project].delete(:namespace_id) + params[:project].delete(:public) unless can?(current_user, :change_public_mode, project) + + allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin + + if allowed_transfer && namespace_id.present? + if namespace_id == Namespace.global_id + if project.namespace.present? + # Transfer to global namespace from anyone + project.transfer(nil) + end + elsif namespace_id.to_i != project.namespace_id + # Transfer to someone namespace + namespace = Namespace.find(namespace_id) + project.transfer(namespace) + end + end + + project.update_attributes(params[:project], as: role) + end + end +end diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index fc78db9e3a7..fc2793a72e7 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -29,7 +29,7 @@ class Admin::ProjectsController < AdminController end def update - status = ProjectUpdateContext.new(project, current_user, params).execute(:admin) + status = Projects::UpdateContext.new(project, current_user, params).execute(:admin) if status redirect_to [:admin, @project], notice: 'Project was successfully updated.' diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 6f1180eaa6b..46096f280b8 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -19,7 +19,7 @@ class ProjectsController < ProjectResourceController end def create - @project = Project.create_by_user(params[:project], current_user) + @project = Projects::CreateContext.new(nil, current_user, params).execute respond_to do |format| flash[:notice] = 'Project was successfully created.' if @project.saved? @@ -35,7 +35,7 @@ class ProjectsController < ProjectResourceController end def update - status = ProjectUpdateContext.new(project, current_user, params).execute + status = Projects::UpdateContext.new(project, current_user, params).execute respond_to do |format| if status diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb index 2d25c8f854d..6d0c6c98191 100644 --- a/app/helpers/namespaces_helper.rb +++ b/app/helpers/namespaces_helper.rb @@ -1,12 +1,13 @@ module NamespacesHelper def namespaces_options(selected = :current_user, scope = :default) - groups = current_user.owned_groups.select {|n| n.type == 'Group'} + if current_user.admin + groups = Group.all + users = Namespace.root + else + groups = current_user.owned_groups.select {|n| n.type == 'Group'} + users = current_user.namespaces.reject {|n| n.type == 'Group'} + end - users = if scope == :all - Namespace.root - else - current_user.namespaces.reject {|n| n.type == 'Group'} - end global_opts = ["Global", [['/', Namespace.global_id]] ] group_opts = ["Groups", groups.map {|g| [g.human_name, g.id]} ] diff --git a/app/models/ability.rb b/app/models/ability.rb index 362877f0b22..c0da9396baa 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -7,7 +7,7 @@ class Ability when "Note" then note_abilities(object, subject) when "Snippet" then snippet_abilities(object, subject) when "MergeRequest" then merge_request_abilities(object, subject) - when "Group" then group_abilities(object, subject) + when "Group", "Namespace" then group_abilities(object, subject) else [] end end @@ -102,7 +102,8 @@ class Ability # Only group owner and administrators can manage group if group.owner == user || user.admin? rules << [ - :manage_group + :manage_group, + :manage_namespace ] end diff --git a/app/models/project.rb b/app/models/project.rb index 62f89e2cd1b..fa38093b7d5 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -116,55 +116,6 @@ class Project < ActiveRecord::Base end end - def create_by_user(params, user) - namespace_id = params.delete(:namespace_id) - - project = Project.new params - - Project.transaction do - - # Parametrize path for project - # - # Ex. - # 'GitLab HQ'.parameterize => "gitlab-hq" - # - project.path = project.name.dup.parameterize - - project.creator = user - - # Apply namespace if user has access to it - # else fallback to user namespace - if namespace_id != Namespace.global_id - project.namespace_id = user.namespace_id - - if namespace_id - group = Group.find_by_id(namespace_id) - if user.can? :manage_group, group - project.namespace_id = namespace_id - end - end - end - - project.save! - - # Add user as project master - project.users_projects.create!(project_access: UsersProject::MASTER, user: user) - - # when project saved no team member exist so - # project repository should be updated after first user add - project.update_repository - end - - project - rescue Gitlab::Gitolite::AccessDenied => ex - project.error_code = :gitolite - project - rescue => ex - project.error_code = :db - project.errors.add(:base, "Can't save project. Please try again later") - project - end - def access_options UsersProject.access_roles end diff --git a/app/models/user.rb b/app/models/user.rb index 7e69f3db84c..7a75379e500 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -152,11 +152,8 @@ class User < ActiveRecord::Base namespaces << self.namespace if self.namespace # Add groups you can manage - namespaces += if admin - Group.all - else - groups.all - end + namespaces += groups.all + namespaces end @@ -234,6 +231,10 @@ class User < ActiveRecord::Base end end + def can_select_namespace? + several_namespaces? || admin + end + def can? action, subject abilities.allowed?(self, action, subject) end diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml index ca57cd30732..9830cdf4f6b 100644 --- a/app/views/dashboard/_sidebar.html.haml +++ b/app/views/dashboard/_sidebar.html.haml @@ -9,6 +9,6 @@ %hr .gitlab-promo - = link_to "Homepage", "http://gitlabhq.com" - = link_to "Blog", "http://blog.gitlabhq.com" + = link_to "Homepage", "http://gitlab.org" + = link_to "Blog", "http://blog.gitlab.org" = link_to "@gitlabhq", "https://twitter.com/gitlabhq" diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 64f931ca887..687463b672c 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -6,6 +6,11 @@ %small = @user.email + .right + = link_to destroy_user_session_path, class: "logout", method: :delete do + %small + %i.icon-signout + Logout %hr = form_for @user, url: profile_path, method: :put, html: { class: "edit_user form-horizontal" } do |f| diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index 8bf96f399f8..aa76048302a 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -9,19 +9,11 @@ Project name is .input = f.text_field :name, placeholder: "Example Project", class: "xxlarge" - %fieldset - %legend Advanced settings: - .control-group - = f.label :path do - Repository - .controls - = text_field_tag :ppath, @repository.path_to_repo, class: "xxlarge", readonly: true - + - unless @repository.heads.empty? + .clearfix + = f.label :default_branch, "Default Branch" + .input= f.select(:default_branch, @repository.heads.map(&:name), {}, style: "width:210px;") - - unless @repository.heads.empty? - .clearfix - = f.label :default_branch, "Default Branch" - .input= f.select(:default_branch, @repository.heads.map(&:name), {}, style: "width:210px;") %fieldset.features %legend Features: @@ -87,4 +79,4 @@ - unless @project.new_record? - if can?(current_user, :remove_project, @project) .right - = link_to 'Remove', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn danger" + = link_to 'Remove Project', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn danger" diff --git a/app/views/projects/_new_form.html.haml b/app/views/projects/_new_form.html.haml index 2391c750bc8..131a4de4218 100644 --- a/app/views/projects/_new_form.html.haml +++ b/app/views/projects/_new_form.html.haml @@ -9,10 +9,10 @@ = f.text_field :name, placeholder: "Example Project", class: "xxlarge" = f.submit 'Create project', class: "btn success project-submit" - - if current_user.several_namespaces? + - if current_user.can_select_namespace? .clearfix = f.label :namespace_id do - %span.cgray Namespace + %span Namespace .input = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'chosen'} %hr diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml index d388988676d..296c8688f47 100644 --- a/app/views/projects/create.js.haml +++ b/app/views/projects/create.js.haml @@ -2,11 +2,9 @@ :plain location.href = "#{project_path(@project)}"; - else - - if @project.git_error? - location.href = "#{errors_githost_path}"; - -else :plain $('.project_new_holder').show(); $("#new_project").replaceWith("#{escape_javascript(render('new_form'))}"); $('.save-project-loader').hide(); new Projects(); + $('select.chosen').chosen() diff --git a/features/project/project.feature b/features/project/project.feature index ad3d06bb41f..23fef69ee48 100644 --- a/features/project/project.feature +++ b/features/project/project.feature @@ -1,4 +1,4 @@ -Feature: Projects +Feature: Project Feature Background: Given I sign in as a user And I own project "Shop" diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index 7a85f57a218..e9ef1495dd1 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -1,4 +1,4 @@ -class Projects < Spinach::FeatureSteps +class ProjectFeature < Spinach::FeatureSteps include SharedAuthentication include SharedProject include SharedPaths diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index 3150be5ef18..1623edb80d0 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -47,7 +47,6 @@ module SharedProject Then 'I should see project settings' do current_path.should == edit_project_path(@project) page.should have_content("Project name is") - page.should have_content("Advanced settings:") page.should have_content("Features:") end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 55c81f3158a..c4717d11155 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -43,7 +43,7 @@ module Gitlab :wall_enabled, :merge_requests_enabled, :wiki_enabled] - @project = Project.create_by_user(attrs, current_user) + @project = Projects::CreateContext.new(nil, attrs, current_user).execute if @project.saved? present @project, with: Entities::Project else -- GitLab