Commit 65b9768c authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Group ownership completely based on users_groups relation now

Before we have only owner_id to determine group owner
With multiple owners per group we should get rid of owner_id in group.
So from now @group.owner will always be nil but
@group.owners return an actual array of users who can admin this group
parent edd2143d
...@@ -20,9 +20,9 @@ class Admin::GroupsController < Admin::ApplicationController ...@@ -20,9 +20,9 @@ class Admin::GroupsController < Admin::ApplicationController
def create def create
@group = Group.new(params[:group]) @group = Group.new(params[:group])
@group.path = @group.name.dup.parameterize if @group.name @group.path = @group.name.dup.parameterize if @group.name
@group.owner = current_user
if @group.save if @group.save
@group.add_owner(current_user)
redirect_to [:admin, @group], notice: 'Group was successfully created.' redirect_to [:admin, @group], notice: 'Group was successfully created.'
else else
render "new" render "new"
...@@ -30,14 +30,7 @@ class Admin::GroupsController < Admin::ApplicationController ...@@ -30,14 +30,7 @@ class Admin::GroupsController < Admin::ApplicationController
end end
def update def update
group_params = params[:group].dup if @group.update_attributes(params[:group])
owner_id =group_params.delete(:owner_id)
if owner_id
@group.change_owner(User.find(owner_id))
end
if @group.update_attributes(group_params)
redirect_to [:admin, @group], notice: 'Group was successfully updated.' redirect_to [:admin, @group], notice: 'Group was successfully updated.'
else else
render "edit" render "edit"
......
...@@ -21,9 +21,9 @@ class GroupsController < ApplicationController ...@@ -21,9 +21,9 @@ class GroupsController < ApplicationController
def create def create
@group = Group.new(params[:group]) @group = Group.new(params[:group])
@group.path = @group.name.dup.parameterize if @group.name @group.path = @group.name.dup.parameterize if @group.name
@group.owner = current_user
if @group.save if @group.save
@group.add_owner(current_user)
redirect_to @group, notice: 'Group was successfully created.' redirect_to @group, notice: 'Group was successfully created.'
else else
render action: "new" render action: "new"
......
...@@ -8,8 +8,8 @@ class Profiles::GroupsController < ApplicationController ...@@ -8,8 +8,8 @@ class Profiles::GroupsController < ApplicationController
def leave def leave
@users_group = group.users_groups.where(user_id: current_user.id).first @users_group = group.users_groups.where(user_id: current_user.id).first
if group.owner == current_user if group.last_owner?(current_user)
redirect_to(profile_groups_path, alert: "You can't leave group. You must transfer it to another owner before leaving.") redirect_to(profile_groups_path, alert: "You can't leave group. You must add at least one more owner to it.")
else else
@users_group.destroy @users_group.destroy
redirect_to(profile_groups_path, info: "You left #{group.name} group.") redirect_to(profile_groups_path, info: "You left #{group.name} group.")
......
...@@ -79,7 +79,7 @@ class Ability ...@@ -79,7 +79,7 @@ class Ability
rules << project_admin_rules rules << project_admin_rules
end end
if project.group && project.group.owners.include?(user) if project.group && project.group.has_owner?(user)
rules << project_admin_rules rules << project_admin_rules
end end
...@@ -159,7 +159,7 @@ class Ability ...@@ -159,7 +159,7 @@ class Ability
end end
# Only group owner and administrators can manage group # Only group owner and administrators can manage group
if group.owners.include?(user) || user.admin? if group.has_owner?(user) || user.admin?
rules << [ rules << [
:manage_group, :manage_group,
:manage_namespace :manage_namespace
......
...@@ -16,14 +16,12 @@ class Group < Namespace ...@@ -16,14 +16,12 @@ class Group < Namespace
has_many :users_groups, dependent: :destroy has_many :users_groups, dependent: :destroy
has_many :users, through: :users_groups has_many :users, through: :users_groups
after_create :add_owner
def human_name def human_name
name name
end end
def owners def owners
@owners ||= (users_groups.owners.map(&:user) << owner).uniq @owners ||= users_groups.owners.map(&:user)
end end
def add_users(user_ids, group_access) def add_users(user_ids, group_access)
...@@ -36,20 +34,19 @@ class Group < Namespace ...@@ -36,20 +34,19 @@ class Group < Namespace
self.users_groups.create(user_id: user.id, group_access: group_access) self.users_groups.create(user_id: user.id, group_access: group_access)
end end
def change_owner(user) def add_owner(user)
self.owner = user self.add_user(user, UsersGroup::OWNER)
membership = users_groups.where(user_id: user.id).first
if membership
membership.update_attributes(group_access: UsersGroup::OWNER)
else
add_owner
end end
def has_owner?(user)
owners.include?(user)
end end
private def last_owner?(user)
has_owner?(user) && owners.size == 1
end
def add_owner def members
self.add_users([owner.id], UsersGroup::OWNER) users_groups
end end
end end
...@@ -20,7 +20,7 @@ class Namespace < ActiveRecord::Base ...@@ -20,7 +20,7 @@ class Namespace < ActiveRecord::Base
has_many :projects, dependent: :destroy has_many :projects, dependent: :destroy
belongs_to :owner, class_name: "User" belongs_to :owner, class_name: "User"
validates :owner, presence: true validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
validates :name, presence: true, uniqueness: true, validates :name, presence: true, uniqueness: true,
length: { within: 0..255 }, length: { within: 0..255 },
format: { with: Gitlab::Regex.name_regex, format: { with: Gitlab::Regex.name_regex,
......
...@@ -249,10 +249,10 @@ class Project < ActiveRecord::Base ...@@ -249,10 +249,10 @@ class Project < ActiveRecord::Base
end end
def owner def owner
if namespace if group
namespace_owner group
else else
creator namespace.try(:owner)
end end
end end
...@@ -276,10 +276,6 @@ class Project < ActiveRecord::Base ...@@ -276,10 +276,6 @@ class Project < ActiveRecord::Base
end end
end end
def namespace_owner
namespace.try(:owner)
end
def path_with_namespace def path_with_namespace
if namespace if namespace
namespace.path + '/' + path namespace.path + '/' + path
......
...@@ -135,7 +135,7 @@ class User < ActiveRecord::Base ...@@ -135,7 +135,7 @@ class User < ActiveRecord::Base
# Remove user from all groups # Remove user from all groups
user.users_groups.find_each do |membership| user.users_groups.find_each do |membership|
# skip owned resources # skip owned resources
next if membership.group.owners.include?(user) next if membership.group.last_owner?(user)
return false unless membership.destroy return false unless membership.destroy
end end
......
...@@ -23,13 +23,15 @@ class SystemHooksService ...@@ -23,13 +23,15 @@ class SystemHooksService
case model case model
when Project when Project
owner = model.owner
data.merge!({ data.merge!({
name: model.name, name: model.name,
path: model.path, path: model.path,
path_with_namespace: model.path_with_namespace, path_with_namespace: model.path_with_namespace,
project_id: model.id, project_id: model.id,
owner_name: model.owner.name, owner_name: owner.name,
owner_email: model.owner.email owner_email: owner.respond_to?(:email) ? owner.email : nil
}) })
when User when User
data.merge!({ data.merge!({
......
...@@ -31,11 +31,8 @@ ...@@ -31,11 +31,8 @@
.clearfix.light.append-bottom-10 .clearfix.light.append-bottom-10
%span %span
%b Owner: %b Members:
- if group.owner %span.badge= group.members.size
= link_to group.owner_name, admin_user_path(group.owner)
- else
(deleted)
\| \|
%span %span
%b Projects: %b Projects:
......
...@@ -24,26 +24,6 @@ ...@@ -24,26 +24,6 @@
%strong %strong
= @group.description = @group.description
%li
%span.light Owned by:
%strong
- if @group.owner
= link_to @group.owner_name, admin_user_path(@group.owner)
- else
(deleted)
.pull-right
= link_to "#", class: "btn btn-small change-owner-link" do
%i.icon-edit
Change owner
%li.change-owner-holder.hide.bgred
.form-holder
%strong.cred New Owner:
= form_for [:admin, @group] do |f|
= users_select_tag(:"group[owner_id]")
.prepend-top-10
= f.submit 'Change Owner', class: "btn btn-remove"
= link_to "Cancel", "#", class: "btn change-owner-cancel-link"
%li %li
%span.light Created at: %span.light Created at:
%strong %strong
...@@ -92,4 +72,5 @@ ...@@ -92,4 +72,5 @@
= link_to user.name, admin_user_path(user) = link_to user.name, admin_user_path(user)
%span.pull-right.light %span.pull-right.light
= member.human_access = member.human_access
= 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
%i.icon-minus.icon-white
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
%span.light Owned by: %span.light Owned by:
%strong %strong
- if @project.owner - if @project.owner
= link_to @project.owner_name, admin_user_path(@project.owner) = link_to @project.owner_name, [:admin, @project.owner]
- else - else
(deleted) (deleted)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment