Commit e3f361faedc24dcfc1a5b57f0913ecb2dbb89247
Exists in
master
and in
4 other branches
Merge branch 'refactor/group_owners' of /home/git/repositories/gitlab/gitlabhq
Showing
27 changed files
with
136 additions
and
114 deletions
Show diff stats
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 < Namespace | @@ -16,14 +16,12 @@ class Group < 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 < Namespace | @@ -36,20 +34,19 @@ class Group < 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 < ActiveRecord::Base | @@ -20,7 +20,7 @@ class Namespace < 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 < ActiveRecord::Base | @@ -249,10 +249,10 @@ class Project < 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 < ActiveRecord::Base | @@ -276,10 +276,6 @@ class Project < 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 < ActiveRecord::Base | @@ -135,7 +135,7 @@ class User < 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 ✓ | 163 | %td.permission-x ✓ |
| 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 ✓ | ||
| 179 | + %td.permission-x ✓ | ||
| 180 | + %td.permission-x ✓ | ||
| 181 | + %td.permission-x ✓ | ||
| 182 | + %td.permission-x ✓ | ||
| 183 | + %tr | ||
| 184 | + %td Edit group | ||
| 185 | + %td | ||
| 186 | + %td | ||
| 187 | + %td | ||
| 188 | + %td | ||
| 189 | + %td.permission-x ✓ | ||
| 190 | + %tr | ||
| 191 | + %td Create project in group | ||
| 192 | + %td | ||
| 193 | + %td | ||
| 194 | + %td | ||
| 195 | + %td | ||
| 196 | + %td.permission-x ✓ | ||
| 197 | + %tr | ||
| 198 | + %td Manage group members | ||
| 199 | + %td | ||
| 200 | + %td | ||
| 201 | + %td | ||
| 202 | + %td | ||
| 203 | + %td.permission-x ✓ | ||
| 204 | + %tr | ||
| 205 | + %td Remove group | ||
| 206 | + %td | ||
| 207 | + %td | ||
| 208 | + %td | ||
| 209 | + %td | ||
| 210 | + %td.permission-x ✓ |
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/schema.rb
| @@ -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 => 20130909132950) do | @@ -129,7 +129,7 @@ ActiveRecord::Schema.define(:version => 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 < Spinach::FeatureSteps | @@ -10,7 +10,8 @@ class Groups < 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 "Group access" do | @@ -10,11 +10,13 @@ describe "Group access" 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 "Group access" do | @@ -23,7 +25,7 @@ describe "Group access" 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 "Group access" do | @@ -35,7 +37,7 @@ describe "Group access" 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 "Group access" do | @@ -47,7 +49,7 @@ describe "Group access" 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 "Group access" do | @@ -59,7 +61,7 @@ describe "Group access" 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 "Group access" do | @@ -71,7 +73,7 @@ describe "Group access" 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 |