Commit e3f361faedc24dcfc1a5b57f0913ecb2dbb89247

Authored by Dmitriy Zaporozhets
2 parents 8674e1c2 c6096e47

Merge branch 'refactor/group_owners' of /home/git/repositories/gitlab/gitlabhq

app/controllers/admin/groups_controller.rb
@@ -20,9 +20,9 @@ class Admin::GroupsController < Admin::ApplicationController @@ -20,9 +20,9 @@ class Admin::GroupsController < Admin::ApplicationController
20 def create 20 def create
21 @group = Group.new(params[:group]) 21 @group = Group.new(params[:group])
22 @group.path = @group.name.dup.parameterize if @group.name 22 @group.path = @group.name.dup.parameterize if @group.name
23 - @group.owner = current_user  
24 23
25 if @group.save 24 if @group.save
  25 + @group.add_owner(current_user)
26 redirect_to [:admin, @group], notice: 'Group was successfully created.' 26 redirect_to [:admin, @group], notice: 'Group was successfully created.'
27 else 27 else
28 render "new" 28 render "new"
@@ -30,14 +30,7 @@ class Admin::GroupsController < Admin::ApplicationController @@ -30,14 +30,7 @@ class Admin::GroupsController < Admin::ApplicationController
30 end 30 end
31 31
32 def update 32 def update
33 - group_params = params[:group].dup  
34 - owner_id =group_params.delete(:owner_id)  
35 -  
36 - if owner_id  
37 - @group.change_owner(User.find(owner_id))  
38 - end  
39 -  
40 - if @group.update_attributes(group_params) 33 + if @group.update_attributes(params[:group])
41 redirect_to [:admin, @group], notice: 'Group was successfully updated.' 34 redirect_to [:admin, @group], notice: 'Group was successfully updated.'
42 else 35 else
43 render "edit" 36 render "edit"
app/controllers/groups_controller.rb
@@ -21,9 +21,9 @@ class GroupsController < ApplicationController @@ -21,9 +21,9 @@ class GroupsController < ApplicationController
21 def create 21 def create
22 @group = Group.new(params[:group]) 22 @group = Group.new(params[:group])
23 @group.path = @group.name.dup.parameterize if @group.name 23 @group.path = @group.name.dup.parameterize if @group.name
24 - @group.owner = current_user  
25 24
26 if @group.save 25 if @group.save
  26 + @group.add_owner(current_user)
27 redirect_to @group, notice: 'Group was successfully created.' 27 redirect_to @group, notice: 'Group was successfully created.'
28 else 28 else
29 render action: "new" 29 render action: "new"
@@ -73,15 +73,7 @@ class GroupsController < ApplicationController @@ -73,15 +73,7 @@ class GroupsController < ApplicationController
73 end 73 end
74 74
75 def update 75 def update
76 - group_params = params[:group].dup  
77 - owner_id = group_params.delete(:owner_id)  
78 -  
79 - if owner_id  
80 - @group.owner = User.find(owner_id)  
81 - @group.save  
82 - end  
83 -  
84 - if @group.update_attributes(group_params) 76 + if @group.update_attributes(params[:group])
85 redirect_to @group, notice: 'Group was successfully updated.' 77 redirect_to @group, notice: 'Group was successfully updated.'
86 else 78 else
87 render action: "edit" 79 render action: "edit"
app/controllers/profiles/groups_controller.rb
@@ -8,8 +8,8 @@ class Profiles::GroupsController < ApplicationController @@ -8,8 +8,8 @@ class Profiles::GroupsController < ApplicationController
8 def leave 8 def leave
9 @users_group = group.users_groups.where(user_id: current_user.id).first 9 @users_group = group.users_groups.where(user_id: current_user.id).first
10 10
11 - if group.owner == current_user  
12 - redirect_to(profile_groups_path, alert: "You can't leave group. You must transfer it to another owner before leaving.") 11 + if group.last_owner?(current_user)
  12 + redirect_to(profile_groups_path, alert: "You can't leave group. You must add at least one more owner to it.")
13 else 13 else
14 @users_group.destroy 14 @users_group.destroy
15 redirect_to(profile_groups_path, info: "You left #{group.name} group.") 15 redirect_to(profile_groups_path, info: "You left #{group.name} group.")
app/controllers/users_groups_controller.rb
@@ -19,7 +19,7 @@ class UsersGroupsController < ApplicationController @@ -19,7 +19,7 @@ class UsersGroupsController < ApplicationController
19 19
20 def destroy 20 def destroy
21 @users_group = @group.users_groups.find(params[:id]) 21 @users_group = @group.users_groups.find(params[:id])
22 - @users_group.destroy unless @users_group.user == @group.owner 22 + @users_group.destroy
23 23
24 respond_to do |format| 24 respond_to do |format|
25 format.html { redirect_to members_group_path(@group), notice: 'User was successfully removed from group.' } 25 format.html { redirect_to members_group_path(@group), notice: 'User was successfully removed from group.' }
app/models/ability.rb
@@ -79,7 +79,7 @@ class Ability @@ -79,7 +79,7 @@ class Ability
79 rules << project_admin_rules 79 rules << project_admin_rules
80 end 80 end
81 81
82 - if project.group && project.group.owners.include?(user) 82 + if project.group && project.group.has_owner?(user)
83 rules << project_admin_rules 83 rules << project_admin_rules
84 end 84 end
85 85
@@ -159,7 +159,7 @@ class Ability @@ -159,7 +159,7 @@ class Ability
159 end 159 end
160 160
161 # Only group owner and administrators can manage group 161 # Only group owner and administrators can manage group
162 - if group.owners.include?(user) || user.admin? 162 + if group.has_owner?(user) || user.admin?
163 rules << [ 163 rules << [
164 :manage_group, 164 :manage_group,
165 :manage_namespace 165 :manage_namespace
app/models/group.rb
@@ -16,14 +16,12 @@ class Group &lt; Namespace @@ -16,14 +16,12 @@ class Group &lt; Namespace
16 has_many :users_groups, dependent: :destroy 16 has_many :users_groups, dependent: :destroy
17 has_many :users, through: :users_groups 17 has_many :users, through: :users_groups
18 18
19 - after_create :add_owner  
20 -  
21 def human_name 19 def human_name
22 name 20 name
23 end 21 end
24 22
25 def owners 23 def owners
26 - @owners ||= (users_groups.owners.map(&:user) << owner).uniq 24 + @owners ||= users_groups.owners.map(&:user)
27 end 25 end
28 26
29 def add_users(user_ids, group_access) 27 def add_users(user_ids, group_access)
@@ -36,20 +34,19 @@ class Group &lt; Namespace @@ -36,20 +34,19 @@ class Group &lt; Namespace
36 self.users_groups.create(user_id: user.id, group_access: group_access) 34 self.users_groups.create(user_id: user.id, group_access: group_access)
37 end 35 end
38 36
39 - def change_owner(user)  
40 - self.owner = user  
41 - membership = users_groups.where(user_id: user.id).first 37 + def add_owner(user)
  38 + self.add_user(user, UsersGroup::OWNER)
  39 + end
42 40
43 - if membership  
44 - membership.update_attributes(group_access: UsersGroup::OWNER)  
45 - else  
46 - add_owner  
47 - end 41 + def has_owner?(user)
  42 + owners.include?(user)
48 end 43 end
49 44
50 - private 45 + def last_owner?(user)
  46 + has_owner?(user) && owners.size == 1
  47 + end
51 48
52 - def add_owner  
53 - self.add_users([owner.id], UsersGroup::OWNER) 49 + def members
  50 + users_groups
54 end 51 end
55 end 52 end
app/models/namespace.rb
@@ -20,7 +20,7 @@ class Namespace &lt; ActiveRecord::Base @@ -20,7 +20,7 @@ class Namespace &lt; ActiveRecord::Base
20 has_many :projects, dependent: :destroy 20 has_many :projects, dependent: :destroy
21 belongs_to :owner, class_name: "User" 21 belongs_to :owner, class_name: "User"
22 22
23 - validates :owner, presence: true 23 + validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
24 validates :name, presence: true, uniqueness: true, 24 validates :name, presence: true, uniqueness: true,
25 length: { within: 0..255 }, 25 length: { within: 0..255 },
26 format: { with: Gitlab::Regex.name_regex, 26 format: { with: Gitlab::Regex.name_regex,
app/models/project.rb
@@ -249,10 +249,10 @@ class Project &lt; ActiveRecord::Base @@ -249,10 +249,10 @@ class Project &lt; ActiveRecord::Base
249 end 249 end
250 250
251 def owner 251 def owner
252 - if namespace  
253 - namespace_owner 252 + if group
  253 + group
254 else 254 else
255 - creator 255 + namespace.try(:owner)
256 end 256 end
257 end 257 end
258 258
@@ -276,10 +276,6 @@ class Project &lt; ActiveRecord::Base @@ -276,10 +276,6 @@ class Project &lt; ActiveRecord::Base
276 end 276 end
277 end 277 end
278 278
279 - def namespace_owner  
280 - namespace.try(:owner)  
281 - end  
282 -  
283 def path_with_namespace 279 def path_with_namespace
284 if namespace 280 if namespace
285 namespace.path + '/' + path 281 namespace.path + '/' + path
app/models/user.rb
@@ -135,7 +135,7 @@ class User &lt; ActiveRecord::Base @@ -135,7 +135,7 @@ class User &lt; ActiveRecord::Base
135 # Remove user from all groups 135 # Remove user from all groups
136 user.users_groups.find_each do |membership| 136 user.users_groups.find_each do |membership|
137 # skip owned resources 137 # skip owned resources
138 - next if membership.group.owners.include?(user) 138 + next if membership.group.last_owner?(user)
139 139
140 return false unless membership.destroy 140 return false unless membership.destroy
141 end 141 end
app/services/system_hooks_service.rb
@@ -23,13 +23,15 @@ class SystemHooksService @@ -23,13 +23,15 @@ class SystemHooksService
23 23
24 case model 24 case model
25 when Project 25 when Project
  26 + owner = model.owner
  27 +
26 data.merge!({ 28 data.merge!({
27 name: model.name, 29 name: model.name,
28 path: model.path, 30 path: model.path,
29 path_with_namespace: model.path_with_namespace, 31 path_with_namespace: model.path_with_namespace,
30 project_id: model.id, 32 project_id: model.id,
31 - owner_name: model.owner.name,  
32 - owner_email: model.owner.email 33 + owner_name: owner.name,
  34 + owner_email: owner.respond_to?(:email) ? owner.email : nil
33 }) 35 })
34 when User 36 when User
35 data.merge!({ 37 data.merge!({
app/views/admin/groups/index.html.haml
@@ -31,11 +31,8 @@ @@ -31,11 +31,8 @@
31 31
32 .clearfix.light.append-bottom-10 32 .clearfix.light.append-bottom-10
33 %span 33 %span
34 - %b Owner:  
35 - - if group.owner  
36 - = link_to group.owner_name, admin_user_path(group.owner)  
37 - - else  
38 - (deleted) 34 + %b Members:
  35 + %span.badge= group.members.size
39 \| 36 \|
40 %span 37 %span
41 %b Projects: 38 %b Projects:
app/views/admin/groups/show.html.haml
@@ -25,26 +25,6 @@ @@ -25,26 +25,6 @@
25 = @group.description 25 = @group.description
26 26
27 %li 27 %li
28 - %span.light Owned by:  
29 - %strong  
30 - - if @group.owner  
31 - = link_to @group.owner_name, admin_user_path(@group.owner)  
32 - - else  
33 - (deleted)  
34 - .pull-right  
35 - = link_to "#", class: "btn btn-small change-owner-link" do  
36 - %i.icon-edit  
37 - Change owner  
38 - %li.change-owner-holder.hide.bgred  
39 - .form-holder  
40 - %strong.cred New Owner:  
41 - = form_for [:admin, @group] do |f|  
42 - = users_select_tag(:"group[owner_id]")  
43 - .prepend-top-10  
44 - = f.submit 'Change Owner', class: "btn btn-remove"  
45 - = link_to "Cancel", "#", class: "btn change-owner-cancel-link"  
46 -  
47 - %li  
48 %span.light Created at: 28 %span.light Created at:
49 %strong 29 %strong
50 = @group.created_at.stamp("March 1, 1999") 30 = @group.created_at.stamp("March 1, 1999")
@@ -92,4 +72,5 @@ @@ -92,4 +72,5 @@
92 = link_to user.name, admin_user_path(user) 72 = link_to user.name, admin_user_path(user)
93 %span.pull-right.light 73 %span.pull-right.light
94 = member.human_access 74 = member.human_access
95 - 75 + = link_to group_users_group_path(@group, member), confirm: remove_user_from_group_message(@group, user), method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
  76 + %i.icon-minus.icon-white
app/views/admin/projects/show.html.haml
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 %span.light Owned by: 25 %span.light Owned by:
26 %strong 26 %strong
27 - if @project.owner 27 - if @project.owner
28 - = link_to @project.owner_name, admin_user_path(@project.owner) 28 + = link_to @project.owner_name, [:admin, @project.owner]
29 - else 29 - else
30 (deleted) 30 (deleted)
31 31
app/views/groups/edit.html.haml
@@ -10,8 +10,6 @@ @@ -10,8 +10,6 @@
10 %i.icon-folder-close 10 %i.icon-folder-close
11 Projects 11 Projects
12 %li 12 %li
13 - = link_to 'Transfer', '#tab-transfer', 'data-toggle' => 'tab'  
14 - %li  
15 = link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab' 13 = link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab'
16 14
17 .span10 15 .span10
@@ -65,17 +63,6 @@ @@ -65,17 +63,6 @@
65 - if @group.projects.blank? 63 - if @group.projects.blank?
66 %p.nothing_here_message This group has no projects yet 64 %p.nothing_here_message This group has no projects yet
67 65
68 - .tab-pane#tab-transfer  
69 - .ui-box.ui-box-danger  
70 - .title Transfer group  
71 - .ui-box-body  
72 - %p  
73 - Transferring group will cause loss of admin control over group and all child projects  
74 - = form_for @group do |f|  
75 - = users_select_tag(:'group[owner_id]')  
76 - %hr  
77 - = f.submit 'Transfer group', class: "btn btn-small btn-remove"  
78 -  
79 .tab-pane#tab-remove 66 .tab-pane#tab-remove
80 .ui-box.ui-box-danger 67 .ui-box.ui-box-danger
81 .title Remove group 68 .title Remove group
app/views/groups/members.html.haml
@@ -2,6 +2,9 @@ @@ -2,6 +2,9 @@
2 Group members 2 Group members
3 %p.light 3 %p.light
4 Members of group have access to all group projects. 4 Members of group have access to all group projects.
  5 + Read more about permissions
  6 + %strong= link_to "here", help_permissions_path, class: "vlink"
  7 +
5 %hr 8 %hr
6 - can_manage_group = current_user.can? :manage_group, @group 9 - can_manage_group = current_user.can? :manage_group, @group
7 .ui-box 10 .ui-box
app/views/help/permissions.html.haml
1 = render layout: 'help/layout' do 1 = render layout: 'help/layout' do
2 %h3.page-title Permissions 2 %h3.page-title Permissions
  3 + %p.light User has different abilities depends on access level he has in particular group or project
  4 + %hr
3 5
  6 + %h4 Project:
4 %table.table 7 %table.table
5 %thead 8 %thead
6 %tr 9 %tr
@@ -158,3 +161,50 @@ @@ -158,3 +161,50 @@
158 %td 161 %td
159 %td 162 %td
160 %td.permission-x &#10003; 163 %td.permission-x &#10003;
  164 +
  165 + %h4 Group
  166 + %table.table
  167 + %thead
  168 + %tr
  169 + %th Action
  170 + %th Guest
  171 + %th Reporter
  172 + %th Developer
  173 + %th Master
  174 + %th Owner
  175 + %tbody
  176 + %tr
  177 + %td Browse group
  178 + %td.permission-x &#10003;
  179 + %td.permission-x &#10003;
  180 + %td.permission-x &#10003;
  181 + %td.permission-x &#10003;
  182 + %td.permission-x &#10003;
  183 + %tr
  184 + %td Edit group
  185 + %td
  186 + %td
  187 + %td
  188 + %td
  189 + %td.permission-x &#10003;
  190 + %tr
  191 + %td Create project in group
  192 + %td
  193 + %td
  194 + %td
  195 + %td
  196 + %td.permission-x &#10003;
  197 + %tr
  198 + %td Manage group members
  199 + %td
  200 + %td
  201 + %td
  202 + %td
  203 + %td.permission-x &#10003;
  204 + %tr
  205 + %td Remove group
  206 + %td
  207 + %td
  208 + %td
  209 + %td
  210 + %td.permission-x &#10003;
app/views/users_groups/_users_group.html.haml
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 %span.pull-right 10 %span.pull-right
11 %strong= member.human_access 11 %strong= member.human_access
12 12
13 - - if show_controls && user != @group.owner && user != current_user 13 + - if show_controls && can?(current_user, :manage_group, @group) && current_user != user
14 = link_to '#', class: "btn-tiny btn js-toggle-button", title: 'Edit access level' do 14 = link_to '#', class: "btn-tiny btn js-toggle-button", title: 'Edit access level' do
15 %i.icon-edit 15 %i.icon-edit
16 = link_to group_users_group_path(@group, member), confirm: remove_user_from_group_message(@group, user), method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do 16 = link_to group_users_group_path(@group, member), confirm: remove_user_from_group_message(@group, user), method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
@@ -20,4 +20,4 @@ @@ -20,4 +20,4 @@
20 = form_for [@group, member], remote: true do |f| 20 = form_for [@group, member], remote: true do |f|
21 .alert.prepend-top-20 21 .alert.prepend-top-20
22 = f.select :group_access, options_for_select(UsersGroup.group_access_roles, member.group_access) 22 = f.select :group_access, options_for_select(UsersGroup.group_access_roles, member.group_access)
23 - = f.submit 'Save', class: 'btn btn-save' 23 + = f.submit 'Save', class: 'btn btn-save btn-small'
db/migrate/20130926081215_change_owner_id_for_group.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class ChangeOwnerIdForGroup < ActiveRecord::Migration
  2 + def up
  3 + change_column :namespaces, :owner_id, :integer, null: true
  4 + end
  5 +
  6 + def down
  7 + change_column :namespaces, :owner_id, :integer, null: false
  8 + end
  9 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20130909132950) do 14 +ActiveRecord::Schema.define(:version => 20130926081215) do
15 15
16 create_table "deploy_keys_projects", :force => true do |t| 16 create_table "deploy_keys_projects", :force => true do |t|
17 t.integer "deploy_key_id", :null => false 17 t.integer "deploy_key_id", :null => false
@@ -129,7 +129,7 @@ ActiveRecord::Schema.define(:version =&gt; 20130909132950) do @@ -129,7 +129,7 @@ ActiveRecord::Schema.define(:version =&gt; 20130909132950) do
129 create_table "namespaces", :force => true do |t| 129 create_table "namespaces", :force => true do |t|
130 t.string "name", :null => false 130 t.string "name", :null => false
131 t.string "path", :null => false 131 t.string "path", :null => false
132 - t.integer "owner_id", :null => false 132 + t.integer "owner_id"
133 t.datetime "created_at", :null => false 133 t.datetime "created_at", :null => false
134 t.datetime "updated_at", :null => false 134 t.datetime "updated_at", :null => false
135 t.string "type" 135 t.string "type"
features/steps/group/group.rb
@@ -10,7 +10,8 @@ class Groups &lt; Spinach::FeatureSteps @@ -10,7 +10,8 @@ class Groups &lt; Spinach::FeatureSteps
10 end 10 end
11 11
12 And 'I have group with projects' do 12 And 'I have group with projects' do
13 - @group = create(:group, owner: current_user) 13 + @group = create(:group)
  14 + @group.add_owner(current_user)
14 @project = create(:project, namespace: @group) 15 @project = create(:project, namespace: @group)
15 @event = create(:closed_issue_event, project: @project) 16 @event = create(:closed_issue_event, project: @project)
16 17
spec/contexts/projects_create_context_spec.rb
@@ -25,13 +25,15 @@ describe Projects::CreateContext do @@ -25,13 +25,15 @@ describe Projects::CreateContext do
25 25
26 context 'group namespace' do 26 context 'group namespace' do
27 before do 27 before do
28 - @group = create :group, owner: @user 28 + @group = create :group
  29 + @group.add_owner(@user)
  30 +
29 @opts.merge!(namespace_id: @group.id) 31 @opts.merge!(namespace_id: @group.id)
30 @project = create_project(@user, @opts) 32 @project = create_project(@user, @opts)
31 end 33 end
32 34
33 it { @project.should be_valid } 35 it { @project.should be_valid }
34 - it { @project.owner.should == @user } 36 + it { @project.owner.should == @group }
35 it { @project.namespace.should == @group } 37 it { @project.namespace.should == @group }
36 end 38 end
37 39
spec/factories.rb
@@ -71,7 +71,6 @@ FactoryGirl.define do @@ -71,7 +71,6 @@ FactoryGirl.define do
71 factory :group do 71 factory :group do
72 sequence(:name) { |n| "group#{n}" } 72 sequence(:name) { |n| "group#{n}" }
73 path { name.downcase.gsub(/\s/, '_') } 73 path { name.downcase.gsub(/\s/, '_') }
74 - owner  
75 type 'Group' 74 type 'Group'
76 end 75 end
77 76
spec/features/security/group_access_spec.rb
@@ -10,11 +10,13 @@ describe &quot;Group access&quot; do @@ -10,11 +10,13 @@ describe &quot;Group access&quot; do
10 describe "Group" do 10 describe "Group" do
11 let(:group) { create(:group) } 11 let(:group) { create(:group) }
12 12
  13 + let(:owner) { create(:owner) }
13 let(:master) { create(:user) } 14 let(:master) { create(:user) }
14 let(:reporter) { create(:user) } 15 let(:reporter) { create(:user) }
15 let(:guest) { create(:user) } 16 let(:guest) { create(:user) }
16 17
17 before do 18 before do
  19 + group.add_user(owner, Gitlab::Access::OWNER)
18 group.add_user(master, Gitlab::Access::MASTER) 20 group.add_user(master, Gitlab::Access::MASTER)
19 group.add_user(reporter, Gitlab::Access::REPORTER) 21 group.add_user(reporter, Gitlab::Access::REPORTER)
20 group.add_user(guest, Gitlab::Access::GUEST) 22 group.add_user(guest, Gitlab::Access::GUEST)
@@ -23,7 +25,7 @@ describe &quot;Group access&quot; do @@ -23,7 +25,7 @@ describe &quot;Group access&quot; do
23 describe "GET /groups/:path" do 25 describe "GET /groups/:path" do
24 subject { group_path(group) } 26 subject { group_path(group) }
25 27
26 - it { should be_allowed_for group.owner } 28 + it { should be_allowed_for owner }
27 it { should be_allowed_for master } 29 it { should be_allowed_for master }
28 it { should be_allowed_for reporter } 30 it { should be_allowed_for reporter }
29 it { should be_allowed_for :admin } 31 it { should be_allowed_for :admin }
@@ -35,7 +37,7 @@ describe &quot;Group access&quot; do @@ -35,7 +37,7 @@ describe &quot;Group access&quot; do
35 describe "GET /groups/:path/issues" do 37 describe "GET /groups/:path/issues" do
36 subject { issues_group_path(group) } 38 subject { issues_group_path(group) }
37 39
38 - it { should be_allowed_for group.owner } 40 + it { should be_allowed_for owner }
39 it { should be_allowed_for master } 41 it { should be_allowed_for master }
40 it { should be_allowed_for reporter } 42 it { should be_allowed_for reporter }
41 it { should be_allowed_for :admin } 43 it { should be_allowed_for :admin }
@@ -47,7 +49,7 @@ describe &quot;Group access&quot; do @@ -47,7 +49,7 @@ describe &quot;Group access&quot; do
47 describe "GET /groups/:path/merge_requests" do 49 describe "GET /groups/:path/merge_requests" do
48 subject { merge_requests_group_path(group) } 50 subject { merge_requests_group_path(group) }
49 51
50 - it { should be_allowed_for group.owner } 52 + it { should be_allowed_for owner }
51 it { should be_allowed_for master } 53 it { should be_allowed_for master }
52 it { should be_allowed_for reporter } 54 it { should be_allowed_for reporter }
53 it { should be_allowed_for :admin } 55 it { should be_allowed_for :admin }
@@ -59,7 +61,7 @@ describe &quot;Group access&quot; do @@ -59,7 +61,7 @@ describe &quot;Group access&quot; do
59 describe "GET /groups/:path/members" do 61 describe "GET /groups/:path/members" do
60 subject { members_group_path(group) } 62 subject { members_group_path(group) }
61 63
62 - it { should be_allowed_for group.owner } 64 + it { should be_allowed_for owner }
63 it { should be_allowed_for master } 65 it { should be_allowed_for master }
64 it { should be_allowed_for reporter } 66 it { should be_allowed_for reporter }
65 it { should be_allowed_for :admin } 67 it { should be_allowed_for :admin }
@@ -71,7 +73,7 @@ describe &quot;Group access&quot; do @@ -71,7 +73,7 @@ describe &quot;Group access&quot; do
71 describe "GET /groups/:path/edit" do 73 describe "GET /groups/:path/edit" do
72 subject { edit_group_path(group) } 74 subject { edit_group_path(group) }
73 75
74 - it { should be_allowed_for group.owner } 76 + it { should be_allowed_for owner }
75 it { should be_denied_for master } 77 it { should be_denied_for master }
76 it { should be_denied_for reporter } 78 it { should be_denied_for reporter }
77 it { should be_allowed_for :admin } 79 it { should be_allowed_for :admin }
spec/models/group_spec.rb
@@ -26,10 +26,10 @@ describe Group do @@ -26,10 +26,10 @@ describe Group do
26 it { should validate_uniqueness_of(:name) } 26 it { should validate_uniqueness_of(:name) }
27 it { should validate_presence_of :path } 27 it { should validate_presence_of :path }
28 it { should validate_uniqueness_of(:path) } 28 it { should validate_uniqueness_of(:path) }
29 - it { should validate_presence_of :owner } 29 + it { should_not validate_presence_of :owner }
30 30
31 describe :users do 31 describe :users do
32 - it { group.users.should == [group.owner] } 32 + it { group.users.should == group.owners }
33 end 33 end
34 34
35 describe :human_name do 35 describe :human_name do
@@ -38,7 +38,7 @@ describe Group do @@ -38,7 +38,7 @@ describe Group do
38 38
39 describe :add_users do 39 describe :add_users do
40 let(:user) { create(:user) } 40 let(:user) { create(:user) }
41 - before { group.add_users([user.id], UsersGroup::MASTER) } 41 + before { group.add_user(user, UsersGroup::MASTER) }
42 42
43 it { group.users_groups.masters.map(&:user).should include(user) } 43 it { group.users_groups.masters.map(&:user).should include(user) }
44 end 44 end
spec/models/project_spec.rb
@@ -85,7 +85,6 @@ describe Project do @@ -85,7 +85,6 @@ describe Project do
85 it { should respond_to(:execute_hooks) } 85 it { should respond_to(:execute_hooks) }
86 it { should respond_to(:transfer) } 86 it { should respond_to(:transfer) }
87 it { should respond_to(:name_with_namespace) } 87 it { should respond_to(:name_with_namespace) }
88 - it { should respond_to(:namespace_owner) }  
89 it { should respond_to(:owner) } 88 it { should respond_to(:owner) }
90 it { should respond_to(:path_with_namespace) } 89 it { should respond_to(:path_with_namespace) }
91 end 90 end
spec/models/user_spec.rb
@@ -130,11 +130,12 @@ describe User do @@ -130,11 +130,12 @@ describe User do
130 before do 130 before do
131 ActiveRecord::Base.observers.enable(:user_observer) 131 ActiveRecord::Base.observers.enable(:user_observer)
132 @user = create :user 132 @user = create :user
133 - @group = create :group, owner: @user 133 + @group = create :group
  134 + @group.add_owner(@user)
134 end 135 end
135 136
136 it { @user.several_namespaces?.should be_true } 137 it { @user.several_namespaces?.should be_true }
137 - it { @user.namespaces.should include(@user.namespace, @group) } 138 + it { @user.namespaces.should include(@user.namespace) }
138 it { @user.authorized_groups.should == [@group] } 139 it { @user.authorized_groups.should == [@group] }
139 it { @user.owned_groups.should == [@group] } 140 it { @user.owned_groups.should == [@group] }
140 end 141 end
@@ -144,9 +145,10 @@ describe User do @@ -144,9 +145,10 @@ describe User do
144 ActiveRecord::Base.observers.enable(:user_observer) 145 ActiveRecord::Base.observers.enable(:user_observer)
145 @user = create :user 146 @user = create :user
146 @user2 = create :user 147 @user2 = create :user
147 - @group = create :group, owner: @user 148 + @group = create :group
  149 + @group.add_owner(@user)
148 150
149 - @group.add_users([@user2.id], UsersGroup::OWNER) 151 + @group.add_user(@user2, UsersGroup::OWNER)
150 end 152 end
151 153
152 it { @user2.several_namespaces?.should be_true } 154 it { @user2.several_namespaces?.should be_true }
spec/requests/api/groups_spec.rb
@@ -6,8 +6,13 @@ describe API::API do @@ -6,8 +6,13 @@ describe API::API do
6 let(:user1) { create(:user) } 6 let(:user1) { create(:user) }
7 let(:user2) { create(:user) } 7 let(:user2) { create(:user) }
8 let(:admin) { create(:admin) } 8 let(:admin) { create(:admin) }
9 - let!(:group1) { create(:group, owner: user1) }  
10 - let!(:group2) { create(:group, owner: user2) } 9 + let!(:group1) { create(:group) }
  10 + let!(:group2) { create(:group) }
  11 +
  12 + before do
  13 + group1.add_owner(user1)
  14 + group2.add_owner(user2)
  15 + end
11 16
12 describe "GET /groups" do 17 describe "GET /groups" do
13 context "when unauthenticated" do 18 context "when unauthenticated" do
@@ -130,14 +135,19 @@ describe API::API do @@ -130,14 +135,19 @@ describe API::API do
130 let(:master) { create(:user) } 135 let(:master) { create(:user) }
131 let(:guest) { create(:user) } 136 let(:guest) { create(:user) }
132 let!(:group_with_members) do 137 let!(:group_with_members) do
133 - group = create(:group, owner: owner) 138 + group = create(:group)
134 group.add_users([reporter.id], UsersGroup::REPORTER) 139 group.add_users([reporter.id], UsersGroup::REPORTER)
135 group.add_users([developer.id], UsersGroup::DEVELOPER) 140 group.add_users([developer.id], UsersGroup::DEVELOPER)
136 group.add_users([master.id], UsersGroup::MASTER) 141 group.add_users([master.id], UsersGroup::MASTER)
137 group.add_users([guest.id], UsersGroup::GUEST) 142 group.add_users([guest.id], UsersGroup::GUEST)
138 group 143 group
139 end 144 end
140 - let!(:group_no_members) { create(:group, owner: owner) } 145 + let!(:group_no_members) { create(:group) }
  146 +
  147 + before do
  148 + group_with_members.add_owner owner
  149 + group_no_members.add_owner owner
  150 + end
141 151
142 describe "GET /groups/:id/members" do 152 describe "GET /groups/:id/members" do
143 context "when authenticated as user that is part or the group" do 153 context "when authenticated as user that is part or the group" do