diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index a492e66611f..e41164d54c6 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -1,5 +1,5 @@ class Admin::GroupsController < AdminController - before_filter :group, only: [:edit, :show, :update, :destroy, :project_update] + before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :project_teams_update] def index @groups = Group.order('name ASC') @@ -12,6 +12,8 @@ class Admin::GroupsController < AdminController @projects = @projects.not_in_group(@group) if @group.projects.present? @projects = @projects.all @projects.reject!(&:empty_repo?) + + @users = User.active end def new @@ -65,6 +67,13 @@ class Admin::GroupsController < AdminController redirect_to :back, notice: 'Group was successfully updated.' end + def project_teams_update + @group.projects.each do |p| + p.add_users_ids_to_team(params[:user_ids], params[:project_access]) + end + redirect_to [:admin, @group], notice: 'Users was successfully added.' + end + def destroy @group.destroy diff --git a/app/models/project.rb b/app/models/project.rb index a72a64c94ea..f5ff3e09b63 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -82,6 +82,7 @@ class Project < ActiveRecord::Base scope :public_only, where(private_flag: false) scope :without_user, ->(user) { where("id NOT IN (:ids)", ids: user.projects.map(&:id) ) } scope :not_in_group, ->(group) { where("id NOT IN (:ids)", ids: group.project_ids ) } + scope :in_group, ->(group) { where(namespace_id: group.id) } scope :sorted_by_activity, ->() { order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") } scope :personal, ->(user) { where(namespace_id: user.namespace_id) } scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } diff --git a/app/models/users_project.rb b/app/models/users_project.rb index 3d76a4df037..34377aa5e66 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -33,6 +33,8 @@ class UsersProject < ActiveRecord::Base delegate :name, :email, to: :user, prefix: true + scope :in_project, ->(project) { where(project_id: project.id) } + class << self def import_team(source_project, target_project) UsersProject.without_repository_callback do diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 41f6d9b3516..e23fea3a3e6 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -44,25 +44,54 @@ %div = f.submit 'Change Owner', class: "btn danger" = link_to "Cancel", "#", class: "btn change-owner-cancel-link" -%fieldset - %legend Projects (#{@group.projects.count}) - %table - %thead - %tr - %th Project name - %th Path - %th Users - %th.cred Danger Zone! - - @group.projects.each do |project| - %tr - %td - = link_to project.name_with_namespace, [:admin, project] - %td - %span.monospace= project.path_with_namespace + ".git" - %td= project.users.count - %td.bgred - = link_to 'Transfer project to global namespace', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Remove project from group and move to global namespace. Are you sure?', method: :delete, class: "btn danger small" +- if @group.projects.any? + %fieldset + %legend Projects (#{@group.projects.count}) + %table + %thead + %tr + %th Project name + %th Path + %th Users + %th.cred Danger Zone! + - @group.projects.each do |project| + %tr + %td + = link_to project.name_with_namespace, [:admin, project] + %td + %span.monospace= project.path_with_namespace + ".git" + %td= project.users.count + %td.bgred + = link_to 'Transfer project to global namespace', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Remove project from group and move to global namespace. Are you sure?', method: :delete, class: "btn danger small" + + = form_tag project_teams_update_admin_group_path(@group), id: "new_team_member", class: "bulk_import", method: :put do + %table.zebra-striped + %thead + %tr + %th Users + %th Project Access: + + - @group.users.each do |u| + %tr{class: "user_#{u.id}"} + %td.name= link_to u.name, admin_user_path(u) + %td.projects_access + - u.projects.in_group(@group).each do |p| + - u_p = u.users_projects.in_project(p).first + = "#{p.name} (#{link_to u_p.project_access_human, edit_admin_team_member_path(u_p) })".html_safe + %tr + %td.input= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5' + %td= select_tag :project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3"} + + %tr + %td= submit_tag 'Add user to projects in group', class: "btn primary" + %td + Read more about project permissions + %strong= link_to "here", help_permissions_path, class: "vlink" + +- else + %fieldset + %legend Group is empty = form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do %fieldset diff --git a/config/routes.rb b/config/routes.rb index 4317962f607..659d1a04b55 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,6 +47,7 @@ Gitlab::Application.routes.draw do resources :groups, constraints: { id: /[^\/]+/ } do member do put :project_update + put :project_teams_update delete :remove_project end end diff --git a/features/admin/groups.feature b/features/admin/groups.feature index e5eab8e6ecb..28f35e3a831 100644 --- a/features/admin/groups.feature +++ b/features/admin/groups.feature @@ -1,6 +1,8 @@ Feature: Admin Groups Background: Given I sign in as an admin + And I have group with projects + And Create gitlab user "John" And I visit admin groups page Scenario: Create a group @@ -8,3 +10,8 @@ Feature: Admin Groups And submit form with new group info Then I should be redirected to group page And I should see newly created group + + Scenario: Add user into projects in group + When I visit admin group page + When I select user "John" from user list as "Reporter" + Then I should see "John" in team list in every project as "Reporter" diff --git a/features/steps/admin/admin_groups.rb b/features/steps/admin/admin_groups.rb index 5386f473320..0271348eb1d 100644 --- a/features/steps/admin/admin_groups.rb +++ b/features/steps/admin/admin_groups.rb @@ -3,10 +3,26 @@ class AdminGroups < Spinach::FeatureSteps include SharedPaths include SharedActiveTab + When 'I visit admin group page' do + visit admin_group_path(current_group) + end + When 'I click new group link' do click_link "New Group" end + And 'I have group with projects' do + @group = create(:group) + @project = create(:project, group: @group) + @event = create(:closed_issue_event, project: @project) + + @project.add_access current_user, :admin + end + + And 'Create gitlab user "John"' do + create(:user, :name => "John") + end + And 'submit form with new group info' do fill_in 'group_name', :with => 'gitlab' click_button "Create group" @@ -19,5 +35,27 @@ class AdminGroups < Spinach::FeatureSteps Then 'I should be redirected to group page' do current_path.should == admin_group_path(Group.last) end + + When 'I select user "John" from user list as "Reporter"' do + user = User.find_by_name("John") + within "#new_team_member" do + select user.name, :from => "user_ids" + select "Reporter", :from => "project_access" + end + click_button "Add user to projects in group" + end + + Then 'I should see "John" in team list in every project as "Reporter"' do + user = User.find_by_name("John") + projects_with_access = find(".user_#{user.id} .projects_access") + projects_with_access.should have_link("Reporter") + end + + protected + + def current_group + @group ||= Group.first + end + end