Merge branch 'use-members-models' into 'refator-members-logic'
Use members models See merge request !1
This commit is contained in:
		
						commit
						07bc48c526
					
				| 
						 | 
					@ -46,10 +46,10 @@ class Admin
 | 
				
			||||||
      modal.hide()
 | 
					      modal.hide()
 | 
				
			||||||
      $('.change-owner-link').show()
 | 
					      $('.change-owner-link').show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $('li.users_project').bind 'ajax:success', ->
 | 
					    $('li.project_member').bind 'ajax:success', ->
 | 
				
			||||||
      Turbolinks.visit(location.href)
 | 
					      Turbolinks.visit(location.href)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $('li.users_group').bind 'ajax:success', ->
 | 
					    $('li.group_member').bind 'ajax:success', ->
 | 
				
			||||||
      Turbolinks.visit(location.href)
 | 
					      Turbolinks.visit(location.href)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Admin = Admin
 | 
					@Admin = Admin
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
class GroupMembers
 | 
					class GroupMembers
 | 
				
			||||||
  constructor: ->
 | 
					  constructor: ->
 | 
				
			||||||
    $('li.users_group').bind 'ajax:success', ->
 | 
					    $('li.group_member').bind 'ajax:success', ->
 | 
				
			||||||
      $(this).fadeOut()
 | 
					      $(this).fadeOut()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@GroupMembers = GroupMembers
 | 
					@GroupMembers = GroupMembers
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ class Admin::GroupsController < Admin::ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    @members = @group.members.order("group_access DESC").page(params[:members_page]).per(30)
 | 
					    @members = @group.members.order("access_level DESC").page(params[:members_page]).per(30)
 | 
				
			||||||
    @projects = @group.projects.page(params[:projects_page]).per(30)
 | 
					    @projects = @group.projects.page(params[:projects_page]).per(30)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@ class Admin::GroupsController < Admin::ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def project_teams_update
 | 
					  def project_teams_update
 | 
				
			||||||
    @group.add_users(params[:user_ids].split(','), params[:group_access])
 | 
					    @group.add_users(params[:user_ids].split(','), params[:access_level])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    redirect_to [:admin, @group], notice: 'Users were successfully added.'
 | 
					    redirect_to [:admin, @group], notice: 'Users were successfully added.'
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,10 +16,10 @@ class Admin::ProjectsController < Admin::ApplicationController
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    if @group
 | 
					    if @group
 | 
				
			||||||
      @group_members = @group.members.order("group_access DESC").page(params[:group_members_page]).per(30)
 | 
					      @group_members = @group.members.order("access_level DESC").page(params[:group_members_page]).per(30)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @project_members = @project.users_projects.page(params[:project_members_page]).per(30)
 | 
					    @project_members = @project.project_members.page(params[:project_members_page]).per(30)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def transfer
 | 
					  def transfer
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
class UsersGroupsController < ApplicationController
 | 
					class Groups::GroupMembersController < ApplicationController
 | 
				
			||||||
  before_filter :group
 | 
					  before_filter :group
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Authorize
 | 
					  # Authorize
 | 
				
			||||||
| 
						 | 
					@ -7,18 +7,18 @@ class UsersGroupsController < ApplicationController
 | 
				
			||||||
  layout 'group'
 | 
					  layout 'group'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def create
 | 
					  def create
 | 
				
			||||||
    @group.add_users(params[:user_ids].split(','), params[:group_access])
 | 
					    @group.add_users(params[:user_ids].split(','), params[:access_level])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    redirect_to members_group_path(@group), notice: 'Users were successfully added.'
 | 
					    redirect_to members_group_path(@group), notice: 'Users were successfully added.'
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def update
 | 
					  def update
 | 
				
			||||||
    @member = @group.users_groups.find(params[:id])
 | 
					    @member = @group.group_members.find(params[:id])
 | 
				
			||||||
    @member.update_attributes(member_params)
 | 
					    @member.update_attributes(member_params)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def destroy
 | 
					  def destroy
 | 
				
			||||||
    @users_group = @group.users_groups.find(params[:id])
 | 
					    @users_group = @group.group_members.find(params[:id])
 | 
				
			||||||
    if can?(current_user, :destroy, @users_group)  # May fail if last owner.
 | 
					    if can?(current_user, :destroy, @users_group)  # May fail if last owner.
 | 
				
			||||||
      @users_group.destroy
 | 
					      @users_group.destroy
 | 
				
			||||||
      respond_to do |format|
 | 
					      respond_to do |format|
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,6 @@ class UsersGroupsController < ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def member_params
 | 
					  def member_params
 | 
				
			||||||
    params.require(:users_group).permit(:group_access, :user_id)
 | 
					    params.require(:group_member).permit(:access_level, :user_id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -65,15 +65,15 @@ class GroupsController < ApplicationController
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def members
 | 
					  def members
 | 
				
			||||||
    @project = group.projects.find(params[:project_id]) if params[:project_id]
 | 
					    @project = group.projects.find(params[:project_id]) if params[:project_id]
 | 
				
			||||||
    @members = group.users_groups
 | 
					    @members = group.group_members
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if params[:search].present?
 | 
					    if params[:search].present?
 | 
				
			||||||
      users = group.users.search(params[:search]).to_a
 | 
					      users = group.users.search(params[:search]).to_a
 | 
				
			||||||
      @members = @members.where(user_id: users)
 | 
					      @members = @members.where(user_id: users)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @members = @members.order('group_access DESC').page(params[:page]).per(50)
 | 
					    @members = @members.order('access_level DESC').page(params[:page]).per(50)
 | 
				
			||||||
    @users_group = UsersGroup.new
 | 
					    @users_group = GroupMember.new
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def edit
 | 
					  def edit
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,11 +2,11 @@ class Profiles::GroupsController < ApplicationController
 | 
				
			||||||
  layout "profile"
 | 
					  layout "profile"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def index
 | 
					  def index
 | 
				
			||||||
    @user_groups = current_user.users_groups.page(params[:page]).per(20)
 | 
					    @user_groups = current_user.group_members.page(params[:page]).per(20)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def leave
 | 
					  def leave
 | 
				
			||||||
    @users_group = group.users_groups.where(user_id: current_user.id).first
 | 
					    @users_group = group.group_members.where(user_id: current_user.id).first
 | 
				
			||||||
    if can?(current_user, :destroy, @users_group)
 | 
					    if can?(current_user, :destroy, @users_group)
 | 
				
			||||||
      @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.")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@ class Profiles::NotificationsController < ApplicationController
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    @notification = current_user.notification
 | 
					    @notification = current_user.notification
 | 
				
			||||||
    @users_projects = current_user.users_projects
 | 
					    @project_members = current_user.project_members
 | 
				
			||||||
    @users_groups = current_user.users_groups
 | 
					    @group_members = current_user.group_members
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def update
 | 
					  def update
 | 
				
			||||||
| 
						 | 
					@ -14,13 +14,13 @@ class Profiles::NotificationsController < ApplicationController
 | 
				
			||||||
               current_user.notification_level = params[:notification_level]
 | 
					               current_user.notification_level = params[:notification_level]
 | 
				
			||||||
               current_user.save
 | 
					               current_user.save
 | 
				
			||||||
             elsif type == 'group'
 | 
					             elsif type == 'group'
 | 
				
			||||||
               users_group = current_user.users_groups.find(params[:notification_id])
 | 
					               users_group = current_user.group_members.find(params[:notification_id])
 | 
				
			||||||
               users_group.notification_level = params[:notification_level]
 | 
					               users_group.notification_level = params[:notification_level]
 | 
				
			||||||
               users_group.save
 | 
					               users_group.save
 | 
				
			||||||
             else
 | 
					             else
 | 
				
			||||||
               users_project = current_user.users_projects.find(params[:notification_id])
 | 
					               project_member = current_user.project_members.find(params[:notification_id])
 | 
				
			||||||
               users_project.notification_level = params[:notification_level]
 | 
					               project_member.notification_level = params[:notification_level]
 | 
				
			||||||
               users_project.save
 | 
					               project_member.save
 | 
				
			||||||
             end
 | 
					             end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,17 +6,17 @@ class Projects::TeamMembersController < Projects::ApplicationController
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def index
 | 
					  def index
 | 
				
			||||||
    @group = @project.group
 | 
					    @group = @project.group
 | 
				
			||||||
    @users_projects = @project.users_projects.order('project_access DESC')
 | 
					    @project_members = @project.project_members.order('access_level DESC')
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def new
 | 
					  def new
 | 
				
			||||||
    @user_project_relation = project.users_projects.new
 | 
					    @user_project_relation = project.project_members.new
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def create
 | 
					  def create
 | 
				
			||||||
    users = User.where(id: params[:user_ids].split(','))
 | 
					    users = User.where(id: params[:user_ids].split(','))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @project.team << [users, params[:project_access]]
 | 
					    @project.team << [users, params[:access_level]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if params[:redirect_to]
 | 
					    if params[:redirect_to]
 | 
				
			||||||
      redirect_to params[:redirect_to]
 | 
					      redirect_to params[:redirect_to]
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ class Projects::TeamMembersController < Projects::ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def update
 | 
					  def update
 | 
				
			||||||
    @user_project_relation = project.users_projects.find_by(user_id: member)
 | 
					    @user_project_relation = project.project_members.find_by(user_id: member)
 | 
				
			||||||
    @user_project_relation.update_attributes(member_params)
 | 
					    @user_project_relation.update_attributes(member_params)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unless @user_project_relation.valid?
 | 
					    unless @user_project_relation.valid?
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ class Projects::TeamMembersController < Projects::ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def destroy
 | 
					  def destroy
 | 
				
			||||||
    @user_project_relation = project.users_projects.find_by(user_id: member)
 | 
					    @user_project_relation = project.project_members.find_by(user_id: member)
 | 
				
			||||||
    @user_project_relation.destroy
 | 
					    @user_project_relation.destroy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    respond_to do |format|
 | 
					    respond_to do |format|
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ class Projects::TeamMembersController < Projects::ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def leave
 | 
					  def leave
 | 
				
			||||||
    project.users_projects.find_by(user_id: current_user).destroy
 | 
					    project.project_members.find_by(user_id: current_user).destroy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    respond_to do |format|
 | 
					    respond_to do |format|
 | 
				
			||||||
      format.html { redirect_to :back }
 | 
					      format.html { redirect_to :back }
 | 
				
			||||||
| 
						 | 
					@ -69,6 +69,6 @@ class Projects::TeamMembersController < Projects::ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def member_params
 | 
					  def member_params
 | 
				
			||||||
    params.require(:team_member).permit(:user_id, :project_access)
 | 
					    params.require(:project_member).permit(:user_id, :access_level)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,10 +19,8 @@ class ProjectsFinder
 | 
				
			||||||
        # Return ALL group projects
 | 
					        # Return ALL group projects
 | 
				
			||||||
        group.projects
 | 
					        group.projects
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        projects_members = UsersProject.where(
 | 
					        projects_members = ProjectMember.in_projects(group.projects).
 | 
				
			||||||
          project_id: group.projects,
 | 
					          with_user(current_user)
 | 
				
			||||||
          user_id: current_user
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if projects_members.any?
 | 
					        if projects_members.any?
 | 
				
			||||||
          # User is a project member
 | 
					          # User is a project member
 | 
				
			||||||
| 
						 | 
					@ -34,7 +32,7 @@ class ProjectsFinder
 | 
				
			||||||
          #
 | 
					          #
 | 
				
			||||||
          group.projects.where(
 | 
					          group.projects.where(
 | 
				
			||||||
            "projects.id IN (?) OR projects.visibility_level IN (?)",
 | 
					            "projects.id IN (?) OR projects.visibility_level IN (?)",
 | 
				
			||||||
            projects_members.pluck(:project_id),
 | 
					            projects_members.pluck(:source_id),
 | 
				
			||||||
            Project.public_and_internal_levels
 | 
					            Project.public_and_internal_levels
 | 
				
			||||||
          )
 | 
					          )
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
module Emails
 | 
					module Emails
 | 
				
			||||||
  module Groups
 | 
					  module Groups
 | 
				
			||||||
    def group_access_granted_email(user_group_id)
 | 
					    def group_access_granted_email(user_group_id)
 | 
				
			||||||
      @membership = UsersGroup.find(user_group_id)
 | 
					      @membership = GroupMember.find(user_group_id)
 | 
				
			||||||
      @group = @membership.group
 | 
					      @group = @membership.group
 | 
				
			||||||
      @target_url = group_url(@group)
 | 
					      @target_url = group_url(@group)
 | 
				
			||||||
      mail(to: @membership.user.email,
 | 
					      mail(to: @membership.user.email,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,10 @@
 | 
				
			||||||
module Emails
 | 
					module Emails
 | 
				
			||||||
  module Projects
 | 
					  module Projects
 | 
				
			||||||
    def project_access_granted_email(user_project_id)
 | 
					    def project_access_granted_email(user_project_id)
 | 
				
			||||||
      @users_project = UsersProject.find user_project_id
 | 
					      @project_member = ProjectMember.find user_project_id
 | 
				
			||||||
      @project = @users_project.project
 | 
					      @project = @project_member.project
 | 
				
			||||||
      @target_url = project_url(@project)
 | 
					      @target_url = project_url(@project)
 | 
				
			||||||
      mail(to: @users_project.user.email,
 | 
					      mail(to: @project_member.user.email,
 | 
				
			||||||
           subject: subject("Access to project was granted"))
 | 
					           subject: subject("Access to project was granted"))
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ class Ability
 | 
				
			||||||
      when "MergeRequest" then merge_request_abilities(user, subject)
 | 
					      when "MergeRequest" then merge_request_abilities(user, subject)
 | 
				
			||||||
      when "Group" then group_abilities(user, subject)
 | 
					      when "Group" then group_abilities(user, subject)
 | 
				
			||||||
      when "Namespace" then namespace_abilities(user, subject)
 | 
					      when "Namespace" then namespace_abilities(user, subject)
 | 
				
			||||||
      when "UsersGroup" then users_group_abilities(user, subject)
 | 
					      when "GroupMember" then users_group_abilities(user, subject)
 | 
				
			||||||
      else []
 | 
					      else []
 | 
				
			||||||
      end.concat(global_abilities(user))
 | 
					      end.concat(global_abilities(user))
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
# == Notifiable concern
 | 
					# == Notifiable concern
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Contains notification functionality shared between UsersProject and UsersGroup
 | 
					# Contains notification functionality
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
module Notifiable
 | 
					module Notifiable
 | 
				
			||||||
  extend ActiveSupport::Concern
 | 
					  extend ActiveSupport::Concern
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,8 +17,8 @@ require 'carrierwave/orm/activerecord'
 | 
				
			||||||
require 'file_size_validator'
 | 
					require 'file_size_validator'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Group < Namespace
 | 
					class Group < Namespace
 | 
				
			||||||
  has_many :users_groups, dependent: :destroy
 | 
					  has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember'
 | 
				
			||||||
  has_many :users, through: :users_groups
 | 
					  has_many :users, through: :group_members
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  validate :avatar_type, if: ->(user) { user.avatar_changed? }
 | 
					  validate :avatar_type, if: ->(user) { user.avatar_changed? }
 | 
				
			||||||
  validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
 | 
					  validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
 | 
				
			||||||
| 
						 | 
					@ -30,22 +30,22 @@ class Group < Namespace
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def owners
 | 
					  def owners
 | 
				
			||||||
    @owners ||= users_groups.owners.map(&:user)
 | 
					    @owners ||= group_members.owners.map(&:user)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def add_users(user_ids, group_access)
 | 
					  def add_users(user_ids, access_level)
 | 
				
			||||||
    user_ids.compact.each do |user_id|
 | 
					    user_ids.compact.each do |user_id|
 | 
				
			||||||
      user = self.users_groups.find_or_initialize_by(user_id: user_id)
 | 
					      user = self.group_members.find_or_initialize_by(user_id: user_id)
 | 
				
			||||||
      user.update_attributes(group_access: group_access)
 | 
					      user.update_attributes(access_level: access_level)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def add_user(user, group_access)
 | 
					  def add_user(user, access_level)
 | 
				
			||||||
    self.users_groups.create(user_id: user.id, group_access: group_access)
 | 
					    self.group_members.create(user_id: user.id, access_level: access_level)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def add_owner(user)
 | 
					  def add_owner(user)
 | 
				
			||||||
    self.add_user(user, UsersGroup::OWNER)
 | 
					    self.add_user(user, Gitlab::Access::OWNER)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def has_owner?(user)
 | 
					  def has_owner?(user)
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ class Group < Namespace
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def members
 | 
					  def members
 | 
				
			||||||
    users_groups
 | 
					    group_members
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def avatar_type
 | 
					  def avatar_type
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +0,0 @@
 | 
				
			||||||
class GroupMember < Member
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
| 
						 | 
					@ -8,11 +8,13 @@ class Member < ActiveRecord::Base
 | 
				
			||||||
  validates :user, presence: true
 | 
					  validates :user, presence: true
 | 
				
			||||||
  validates :source, presence: true
 | 
					  validates :source, presence: true
 | 
				
			||||||
  validates :user_id, uniqueness: { scope: [:source_type, :source_id], message: "already exists in source" }
 | 
					  validates :user_id, uniqueness: { scope: [:source_type, :source_id], message: "already exists in source" }
 | 
				
			||||||
  validates :access_level, inclusion: { in: Gitlab::Access.values }, presence: true
 | 
					  validates :access_level, inclusion: { in: Gitlab::Access.all_values }, presence: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  scope :guests, -> { where(group_access: GUEST) }
 | 
					  scope :guests, -> { where(access_level: GUEST) }
 | 
				
			||||||
  scope :reporters, -> { where(group_access: REPORTER) }
 | 
					  scope :reporters, -> { where(access_level: REPORTER) }
 | 
				
			||||||
  scope :developers, -> { where(group_access: DEVELOPER) }
 | 
					  scope :developers, -> { where(access_level: DEVELOPER) }
 | 
				
			||||||
  scope :masters,  -> { where(group_access: MASTER) }
 | 
					  scope :masters,  -> { where(access_level: MASTER) }
 | 
				
			||||||
  scope :owners,  -> { where(group_access: OWNER) }
 | 
					  scope :owners,  -> { where(access_level: OWNER) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  delegate :name, :username, :email, to: :user, prefix: true
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					class GroupMember < Member
 | 
				
			||||||
 | 
					  SOURCE_TYPE = 'Namespace'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  belongs_to :group, class_name: 'Group', foreign_key: 'source_id'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Make sure group member points only to group as it source
 | 
				
			||||||
 | 
					  default_value_for :source_type, SOURCE_TYPE
 | 
				
			||||||
 | 
					  default_value_for :notification_level, Notification::N_GLOBAL
 | 
				
			||||||
 | 
					  validates_format_of :source_type, with: /\ANamespace\z/
 | 
				
			||||||
 | 
					  default_scope { where(source_type: SOURCE_TYPE) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  scope :with_group, ->(group) { where(source_id: group.id) }
 | 
				
			||||||
 | 
					  scope :with_user, ->(user) { where(user_id: user.id) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  after_create :notify_create
 | 
				
			||||||
 | 
					  after_update :notify_update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def self.access_level_roles
 | 
				
			||||||
 | 
					    Gitlab::Access.options_with_owner
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def group
 | 
				
			||||||
 | 
					    source
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def access_field
 | 
				
			||||||
 | 
					    access_level
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def notify_create
 | 
				
			||||||
 | 
					    notification_service.new_group_member(self)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def notify_update
 | 
				
			||||||
 | 
					    if access_level_changed?
 | 
				
			||||||
 | 
					      notification_service.update_group_member(self)
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def notification_service
 | 
				
			||||||
 | 
					    NotificationService.new
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,137 @@
 | 
				
			||||||
 | 
					class ProjectMember < Member
 | 
				
			||||||
 | 
					  SOURCE_TYPE = 'Project'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  include Gitlab::ShellAdapter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  belongs_to :project, class_name: 'Project', foreign_key: 'source_id'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Make sure project member points only to project as it source
 | 
				
			||||||
 | 
					  default_value_for :source_type, SOURCE_TYPE
 | 
				
			||||||
 | 
					  default_value_for :notification_level, Notification::N_GLOBAL
 | 
				
			||||||
 | 
					  validates_format_of :source_type, with: /\AProject\z/
 | 
				
			||||||
 | 
					  default_scope { where(source_type: SOURCE_TYPE) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  after_create :post_create_hook
 | 
				
			||||||
 | 
					  after_update :post_update_hook
 | 
				
			||||||
 | 
					  after_destroy :post_destroy_hook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  scope :in_project, ->(project) { where(source_id: project.id) }
 | 
				
			||||||
 | 
					  scope :in_projects, ->(projects) { where(source_id: projects.pluck(:id)) }
 | 
				
			||||||
 | 
					  scope :with_user, ->(user) { where(user_id: user.id) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  class << self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Add users to project teams with passed access option
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # access can be an integer representing a access code
 | 
				
			||||||
 | 
					    # or symbol like :master representing role
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # Ex.
 | 
				
			||||||
 | 
					    #   add_users_into_projects(
 | 
				
			||||||
 | 
					    #     project_ids,
 | 
				
			||||||
 | 
					    #     user_ids,
 | 
				
			||||||
 | 
					    #     ProjectMember::MASTER
 | 
				
			||||||
 | 
					    #   )
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    #   add_users_into_projects(
 | 
				
			||||||
 | 
					    #     project_ids,
 | 
				
			||||||
 | 
					    #     user_ids,
 | 
				
			||||||
 | 
					    #     :master
 | 
				
			||||||
 | 
					    #   )
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    def add_users_into_projects(project_ids, user_ids, access)
 | 
				
			||||||
 | 
					      access_level = if roles_hash.has_key?(access)
 | 
				
			||||||
 | 
					                       roles_hash[access]
 | 
				
			||||||
 | 
					                     elsif roles_hash.values.include?(access.to_i)
 | 
				
			||||||
 | 
					                       access
 | 
				
			||||||
 | 
					                     else
 | 
				
			||||||
 | 
					                       raise "Non valid access"
 | 
				
			||||||
 | 
					                     end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ProjectMember.transaction do
 | 
				
			||||||
 | 
					        project_ids.each do |project_id|
 | 
				
			||||||
 | 
					          user_ids.each do |user_id|
 | 
				
			||||||
 | 
					            member = ProjectMember.new(access_level: access_level, user_id: user_id)
 | 
				
			||||||
 | 
					            member.source_id = project_id
 | 
				
			||||||
 | 
					            member.save
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      true
 | 
				
			||||||
 | 
					    rescue
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def truncate_teams(project_ids)
 | 
				
			||||||
 | 
					      ProjectMember.transaction do
 | 
				
			||||||
 | 
					        members = ProjectMember.where(source_id: project_ids)
 | 
				
			||||||
 | 
					        members.each do |member|
 | 
				
			||||||
 | 
					          member.destroy
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      true
 | 
				
			||||||
 | 
					    rescue
 | 
				
			||||||
 | 
					      false
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def truncate_team project
 | 
				
			||||||
 | 
					      truncate_teams [project.id]
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def roles_hash
 | 
				
			||||||
 | 
					      Gitlab::Access.sym_options
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def access_roles
 | 
				
			||||||
 | 
					      Gitlab::Access.options
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def access_field
 | 
				
			||||||
 | 
					    access_level
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def owner?
 | 
				
			||||||
 | 
					    project.owner == user
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def post_create_hook
 | 
				
			||||||
 | 
					    Event.create(
 | 
				
			||||||
 | 
					      project_id: self.project.id,
 | 
				
			||||||
 | 
					      action: Event::JOINED,
 | 
				
			||||||
 | 
					      author_id: self.user.id
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    notification_service.new_team_member(self) unless owner?
 | 
				
			||||||
 | 
					    system_hook_service.execute_hooks_for(self, :create)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def post_update_hook
 | 
				
			||||||
 | 
					    notification_service.update_team_member(self) if self.access_level_changed?
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def post_destroy_hook
 | 
				
			||||||
 | 
					    Event.create(
 | 
				
			||||||
 | 
					      project_id: self.project.id,
 | 
				
			||||||
 | 
					      action: Event::LEFT,
 | 
				
			||||||
 | 
					      author_id: self.user.id
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    system_hook_service.execute_hooks_for(self, :destroy)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def notification_service
 | 
				
			||||||
 | 
					    NotificationService.new
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def system_hook_service
 | 
				
			||||||
 | 
					    SystemHooksService.new
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def project
 | 
				
			||||||
 | 
					    source
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -79,8 +79,8 @@ class Project < ActiveRecord::Base
 | 
				
			||||||
  has_many :snippets,           dependent: :destroy, class_name: "ProjectSnippet"
 | 
					  has_many :snippets,           dependent: :destroy, class_name: "ProjectSnippet"
 | 
				
			||||||
  has_many :hooks,              dependent: :destroy, class_name: "ProjectHook"
 | 
					  has_many :hooks,              dependent: :destroy, class_name: "ProjectHook"
 | 
				
			||||||
  has_many :protected_branches, dependent: :destroy
 | 
					  has_many :protected_branches, dependent: :destroy
 | 
				
			||||||
  has_many :users_projects, dependent: :destroy
 | 
					  has_many :project_members, dependent: :destroy, as: :source, class_name: 'ProjectMember'
 | 
				
			||||||
  has_many :users, through: :users_projects
 | 
					  has_many :users, through: :project_members
 | 
				
			||||||
  has_many :deploy_keys_projects, dependent: :destroy
 | 
					  has_many :deploy_keys_projects, dependent: :destroy
 | 
				
			||||||
  has_many :deploy_keys, through: :deploy_keys_projects
 | 
					  has_many :deploy_keys, through: :deploy_keys_projects
 | 
				
			||||||
  has_many :users_star_projects, dependent: :destroy
 | 
					  has_many :users_star_projects, dependent: :destroy
 | 
				
			||||||
| 
						 | 
					@ -353,12 +353,12 @@ class Project < ActiveRecord::Base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def team_member_by_name_or_email(name = nil, email = nil)
 | 
					  def team_member_by_name_or_email(name = nil, email = nil)
 | 
				
			||||||
    user = users.where("name like ? or email like ?", name, email).first
 | 
					    user = users.where("name like ? or email like ?", name, email).first
 | 
				
			||||||
    users_projects.where(user: user) if user
 | 
					    project_members.where(user: user) if user
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Get Team Member record by user id
 | 
					  # Get Team Member record by user id
 | 
				
			||||||
  def team_member_by_id(user_id)
 | 
					  def team_member_by_id(user_id)
 | 
				
			||||||
    users_projects.find_by(user_id: user_id)
 | 
					    project_members.find_by(user_id: user_id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def name_with_namespace
 | 
					  def name_with_namespace
 | 
				
			||||||
| 
						 | 
					@ -555,7 +555,7 @@ class Project < ActiveRecord::Base
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def project_member(user)
 | 
					  def project_member(user)
 | 
				
			||||||
    users_projects.where(user_id: user).first
 | 
					    project_members.where(user_id: user).first
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def default_branch
 | 
					  def default_branch
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +0,0 @@
 | 
				
			||||||
class ProjectMember < Member
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
| 
						 | 
					@ -32,12 +32,12 @@ class ProjectTeam
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def find_tm(user_id)
 | 
					  def find_tm(user_id)
 | 
				
			||||||
    tm = project.users_projects.find_by(user_id: user_id)
 | 
					    tm = project.project_members.find_by(user_id: user_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # If user is not in project members
 | 
					    # If user is not in project members
 | 
				
			||||||
    # we should check for group membership
 | 
					    # we should check for group membership
 | 
				
			||||||
    if group && !tm
 | 
					    if group && !tm
 | 
				
			||||||
      tm = group.users_groups.find_by(user_id: user_id)
 | 
					      tm = group.group_members.find_by(user_id: user_id)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tm
 | 
					    tm
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,7 @@ class ProjectTeam
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def add_users_ids(user_ids, access)
 | 
					  def add_users_ids(user_ids, access)
 | 
				
			||||||
    UsersProject.add_users_into_projects(
 | 
					    ProjectMember.add_users_into_projects(
 | 
				
			||||||
      [project.id],
 | 
					      [project.id],
 | 
				
			||||||
      user_ids,
 | 
					      user_ids,
 | 
				
			||||||
      access
 | 
					      access
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ class ProjectTeam
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Remove all users from project team
 | 
					  # Remove all users from project team
 | 
				
			||||||
  def truncate
 | 
					  def truncate
 | 
				
			||||||
    UsersProject.truncate_team(project)
 | 
					    ProjectMember.truncate_team(project)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def users
 | 
					  def users
 | 
				
			||||||
| 
						 | 
					@ -91,8 +91,8 @@ class ProjectTeam
 | 
				
			||||||
  def import(source_project)
 | 
					  def import(source_project)
 | 
				
			||||||
    target_project = project
 | 
					    target_project = project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    source_team = source_project.users_projects.to_a
 | 
					    source_team = source_project.project_members.to_a
 | 
				
			||||||
    target_user_ids = target_project.users_projects.pluck(:user_id)
 | 
					    target_user_ids = target_project.project_members.pluck(:user_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    source_team.reject! do |tm|
 | 
					    source_team.reject! do |tm|
 | 
				
			||||||
      # Skip if user already present in team
 | 
					      # Skip if user already present in team
 | 
				
			||||||
| 
						 | 
					@ -102,11 +102,11 @@ class ProjectTeam
 | 
				
			||||||
    source_team.map! do |tm|
 | 
					    source_team.map! do |tm|
 | 
				
			||||||
      new_tm = tm.dup
 | 
					      new_tm = tm.dup
 | 
				
			||||||
      new_tm.id = nil
 | 
					      new_tm.id = nil
 | 
				
			||||||
      new_tm.project_id = target_project.id
 | 
					      new_tm.source = target_project
 | 
				
			||||||
      new_tm
 | 
					      new_tm
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UsersProject.transaction do
 | 
					    ProjectMember.transaction do
 | 
				
			||||||
      source_team.each do |tm|
 | 
					      source_team.each do |tm|
 | 
				
			||||||
        tm.save
 | 
					        tm.save
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
| 
						 | 
					@ -135,10 +135,10 @@ class ProjectTeam
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def max_tm_access(user_id)
 | 
					  def max_tm_access(user_id)
 | 
				
			||||||
    access = []
 | 
					    access = []
 | 
				
			||||||
    access << project.users_projects.find_by(user_id: user_id).try(:access_field)
 | 
					    access << project.project_members.find_by(user_id: user_id).try(:access_field)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if group
 | 
					    if group
 | 
				
			||||||
      access << group.users_groups.find_by(user_id: user_id).try(:access_field)
 | 
					      access << group.group_members.find_by(user_id: user_id).try(:access_field)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    access.compact.max
 | 
					    access.compact.max
 | 
				
			||||||
| 
						 | 
					@ -147,8 +147,8 @@ class ProjectTeam
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def fetch_members(level = nil)
 | 
					  def fetch_members(level = nil)
 | 
				
			||||||
    project_members = project.users_projects
 | 
					    project_members = project.project_members
 | 
				
			||||||
    group_members = group ? group.users_groups : []
 | 
					    group_members = group ? group.group_members : []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if level
 | 
					    if level
 | 
				
			||||||
      project_members = project_members.send(level)
 | 
					      project_members = project_members.send(level)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,21 +81,23 @@ class User < ActiveRecord::Base
 | 
				
			||||||
  has_many :emails, dependent: :destroy
 | 
					  has_many :emails, dependent: :destroy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Groups
 | 
					  # Groups
 | 
				
			||||||
  has_many :users_groups, dependent: :destroy
 | 
					  has_many :members, dependent: :destroy
 | 
				
			||||||
  has_many :groups, through: :users_groups
 | 
					  has_many :project_members, source: 'ProjectMember'
 | 
				
			||||||
  has_many :owned_groups, -> { where users_groups: { group_access: UsersGroup::OWNER } }, through: :users_groups, source: :group
 | 
					  has_many :group_members, source: 'GroupMember'
 | 
				
			||||||
  has_many :masters_groups, -> { where users_groups: { group_access: UsersGroup::MASTER } }, through: :users_groups, source: :group
 | 
					  has_many :groups, through: :group_members
 | 
				
			||||||
 | 
					  has_many :owned_groups, -> { where members: { access_level: Gitlab::Access::OWNER } }, through: :group_members, source: :group
 | 
				
			||||||
 | 
					  has_many :masters_groups, -> { where members: { access_level: Gitlab::Access::MASTER } }, through: :group_members, source: :group
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Projects
 | 
					  # Projects
 | 
				
			||||||
  has_many :groups_projects,          through: :groups, source: :projects
 | 
					  has_many :groups_projects,          through: :groups, source: :projects
 | 
				
			||||||
  has_many :personal_projects,        through: :namespace, source: :projects
 | 
					  has_many :personal_projects,        through: :namespace, source: :projects
 | 
				
			||||||
  has_many :projects,                 through: :users_projects
 | 
					  has_many :projects,                 through: :project_members
 | 
				
			||||||
  has_many :created_projects,         foreign_key: :creator_id, class_name: 'Project'
 | 
					  has_many :created_projects,         foreign_key: :creator_id, class_name: 'Project'
 | 
				
			||||||
  has_many :users_star_projects, dependent: :destroy
 | 
					  has_many :users_star_projects, dependent: :destroy
 | 
				
			||||||
  has_many :starred_projects, through: :users_star_projects, source: :project
 | 
					  has_many :starred_projects, through: :users_star_projects, source: :project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  has_many :snippets,                 dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
 | 
					  has_many :snippets,                 dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
 | 
				
			||||||
  has_many :users_projects,           dependent: :destroy
 | 
					  has_many :project_members,          dependent: :destroy, class_name: 'ProjectMember'
 | 
				
			||||||
  has_many :issues,                   dependent: :destroy, foreign_key: :author_id
 | 
					  has_many :issues,                   dependent: :destroy, foreign_key: :author_id
 | 
				
			||||||
  has_many :notes,                    dependent: :destroy, foreign_key: :author_id
 | 
					  has_many :notes,                    dependent: :destroy, foreign_key: :author_id
 | 
				
			||||||
  has_many :merge_requests,           dependent: :destroy, foreign_key: :author_id
 | 
					  has_many :merge_requests,           dependent: :destroy, foreign_key: :author_id
 | 
				
			||||||
| 
						 | 
					@ -140,7 +142,7 @@ class User < ActiveRecord::Base
 | 
				
			||||||
  state_machine :state, initial: :active do
 | 
					  state_machine :state, initial: :active do
 | 
				
			||||||
    after_transition any => :blocked do |user, transition|
 | 
					    after_transition any => :blocked do |user, transition|
 | 
				
			||||||
      # Remove user from all projects and
 | 
					      # Remove user from all projects and
 | 
				
			||||||
      user.users_projects.find_each do |membership|
 | 
					      user.project_members.find_each do |membership|
 | 
				
			||||||
        # skip owned resources
 | 
					        # skip owned resources
 | 
				
			||||||
        next if membership.project.owner == user
 | 
					        next if membership.project.owner == user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,7 +150,7 @@ class User < ActiveRecord::Base
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Remove user from all groups
 | 
					      # Remove user from all groups
 | 
				
			||||||
      user.users_groups.find_each do |membership|
 | 
					      user.group_members.find_each do |membership|
 | 
				
			||||||
        # skip owned resources
 | 
					        # skip owned resources
 | 
				
			||||||
        next if membership.group.last_owner?(user)
 | 
					        next if membership.group.last_owner?(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -175,7 +177,7 @@ class User < ActiveRecord::Base
 | 
				
			||||||
  scope :in_team, ->(team){ where(id: team.member_ids) }
 | 
					  scope :in_team, ->(team){ where(id: team.member_ids) }
 | 
				
			||||||
  scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
 | 
					  scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
 | 
				
			||||||
  scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
 | 
					  scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
 | 
				
			||||||
  scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') }
 | 
					  scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') }
 | 
				
			||||||
  scope :ldap, -> { where(provider:  'ldap') }
 | 
					  scope :ldap, -> { where(provider:  'ldap') }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active  }
 | 
					  scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active  }
 | 
				
			||||||
| 
						 | 
					@ -295,7 +297,7 @@ class User < ActiveRecord::Base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Team membership in authorized projects
 | 
					  # Team membership in authorized projects
 | 
				
			||||||
  def tm_in_authorized_projects
 | 
					  def tm_in_authorized_projects
 | 
				
			||||||
    UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
 | 
					    ProjectMember.where(source_id: authorized_projects.map(&:id), user_id: self.id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def is_admin?
 | 
					  def is_admin?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,61 +0,0 @@
 | 
				
			||||||
# == Schema Information
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Table name: users_groups
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
#  id                 :integer          not null, primary key
 | 
					 | 
				
			||||||
#  group_access       :integer          not null
 | 
					 | 
				
			||||||
#  group_id           :integer          not null
 | 
					 | 
				
			||||||
#  user_id            :integer          not null
 | 
					 | 
				
			||||||
#  created_at         :datetime
 | 
					 | 
				
			||||||
#  updated_at         :datetime
 | 
					 | 
				
			||||||
#  notification_level :integer          default(3), not null
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UsersGroup < ActiveRecord::Base
 | 
					 | 
				
			||||||
  include Notifiable
 | 
					 | 
				
			||||||
  include Gitlab::Access
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def self.group_access_roles
 | 
					 | 
				
			||||||
    Gitlab::Access.options_with_owner
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  belongs_to :user
 | 
					 | 
				
			||||||
  belongs_to :group
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope :guests, -> { where(group_access: GUEST) }
 | 
					 | 
				
			||||||
  scope :reporters, -> { where(group_access: REPORTER) }
 | 
					 | 
				
			||||||
  scope :developers, -> { where(group_access: DEVELOPER) }
 | 
					 | 
				
			||||||
  scope :masters,  -> { where(group_access: MASTER) }
 | 
					 | 
				
			||||||
  scope :owners,  -> { where(group_access: OWNER) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope :with_group, ->(group) { where(group_id: group.id) }
 | 
					 | 
				
			||||||
  scope :with_user, ->(user) { where(user_id: user.id) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  after_create :notify_create
 | 
					 | 
				
			||||||
  after_update :notify_update
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  validates :group_access, inclusion: { in: UsersGroup.group_access_roles.values }, presence: true
 | 
					 | 
				
			||||||
  validates :user_id, presence: true
 | 
					 | 
				
			||||||
  validates :group_id, presence: true
 | 
					 | 
				
			||||||
  validates :user_id, uniqueness: { scope: [:group_id], message: "already exists in group" }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  delegate :name, :username, :email, to: :user, prefix: true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def access_field
 | 
					 | 
				
			||||||
    group_access
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def notify_create
 | 
					 | 
				
			||||||
    notification_service.new_group_member(self)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def notify_update
 | 
					 | 
				
			||||||
    if group_access_changed?
 | 
					 | 
				
			||||||
      notification_service.update_group_member(self)
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def notification_service
 | 
					 | 
				
			||||||
    NotificationService.new
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,152 +0,0 @@
 | 
				
			||||||
# == Schema Information
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Table name: users_projects
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
#  id                 :integer          not null, primary key
 | 
					 | 
				
			||||||
#  user_id            :integer          not null
 | 
					 | 
				
			||||||
#  project_id         :integer          not null
 | 
					 | 
				
			||||||
#  created_at         :datetime
 | 
					 | 
				
			||||||
#  updated_at         :datetime
 | 
					 | 
				
			||||||
#  project_access     :integer          default(0), not null
 | 
					 | 
				
			||||||
#  notification_level :integer          default(3), not null
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UsersProject < ActiveRecord::Base
 | 
					 | 
				
			||||||
  include Gitlab::ShellAdapter
 | 
					 | 
				
			||||||
  include Notifiable
 | 
					 | 
				
			||||||
  include Gitlab::Access
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  belongs_to :user
 | 
					 | 
				
			||||||
  belongs_to :project
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  validates :user, presence: true
 | 
					 | 
				
			||||||
  validates :user_id, uniqueness: { scope: [:project_id], message: "already exists in project" }
 | 
					 | 
				
			||||||
  validates :project_access, inclusion: { in: Gitlab::Access.values }, presence: true
 | 
					 | 
				
			||||||
  validates :project, presence: true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  delegate :name, :username, :email, to: :user, prefix: true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope :guests, -> { where(project_access: GUEST) }
 | 
					 | 
				
			||||||
  scope :reporters, -> { where(project_access: REPORTER) }
 | 
					 | 
				
			||||||
  scope :developers, -> { where(project_access: DEVELOPER) }
 | 
					 | 
				
			||||||
  scope :masters,  -> { where(project_access: MASTER) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope :in_project, ->(project) { where(project_id: project.id) }
 | 
					 | 
				
			||||||
  scope :in_projects, ->(projects) { where(project_id: projects.map { |p| p.id }) }
 | 
					 | 
				
			||||||
  scope :with_user, ->(user) { where(user_id: user.id) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  after_create :post_create_hook
 | 
					 | 
				
			||||||
  after_update :post_update_hook
 | 
					 | 
				
			||||||
  after_destroy :post_destroy_hook
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  class << self
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Add users to project teams with passed access option
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # access can be an integer representing a access code
 | 
					 | 
				
			||||||
    # or symbol like :master representing role
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Ex.
 | 
					 | 
				
			||||||
    #   add_users_into_projects(
 | 
					 | 
				
			||||||
    #     project_ids,
 | 
					 | 
				
			||||||
    #     user_ids,
 | 
					 | 
				
			||||||
    #     UsersProject::MASTER
 | 
					 | 
				
			||||||
    #   )
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    #   add_users_into_projects(
 | 
					 | 
				
			||||||
    #     project_ids,
 | 
					 | 
				
			||||||
    #     user_ids,
 | 
					 | 
				
			||||||
    #     :master
 | 
					 | 
				
			||||||
    #   )
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    def add_users_into_projects(project_ids, user_ids, access)
 | 
					 | 
				
			||||||
      project_access = if roles_hash.has_key?(access)
 | 
					 | 
				
			||||||
                         roles_hash[access]
 | 
					 | 
				
			||||||
                       elsif roles_hash.values.include?(access.to_i)
 | 
					 | 
				
			||||||
                         access
 | 
					 | 
				
			||||||
                       else
 | 
					 | 
				
			||||||
                         raise "Non valid access"
 | 
					 | 
				
			||||||
                       end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      UsersProject.transaction do
 | 
					 | 
				
			||||||
        project_ids.each do |project_id|
 | 
					 | 
				
			||||||
          user_ids.each do |user_id|
 | 
					 | 
				
			||||||
            users_project = UsersProject.new(project_access: project_access, user_id: user_id)
 | 
					 | 
				
			||||||
            users_project.project_id = project_id
 | 
					 | 
				
			||||||
            users_project.save
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      true
 | 
					 | 
				
			||||||
    rescue
 | 
					 | 
				
			||||||
      false
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def truncate_teams(project_ids)
 | 
					 | 
				
			||||||
      UsersProject.transaction do
 | 
					 | 
				
			||||||
        users_projects = UsersProject.where(project_id: project_ids)
 | 
					 | 
				
			||||||
        users_projects.each do |users_project|
 | 
					 | 
				
			||||||
          users_project.destroy
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      true
 | 
					 | 
				
			||||||
    rescue
 | 
					 | 
				
			||||||
      false
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def truncate_team project
 | 
					 | 
				
			||||||
      truncate_teams [project.id]
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def roles_hash
 | 
					 | 
				
			||||||
      Gitlab::Access.sym_options
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def access_roles
 | 
					 | 
				
			||||||
      Gitlab::Access.options
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def access_field
 | 
					 | 
				
			||||||
    project_access
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def owner?
 | 
					 | 
				
			||||||
    project.owner == user
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def post_create_hook
 | 
					 | 
				
			||||||
    Event.create(
 | 
					 | 
				
			||||||
      project_id: self.project.id,
 | 
					 | 
				
			||||||
      action: Event::JOINED,
 | 
					 | 
				
			||||||
      author_id: self.user.id
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    notification_service.new_team_member(self) unless owner?
 | 
					 | 
				
			||||||
    system_hook_service.execute_hooks_for(self, :create)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def post_update_hook
 | 
					 | 
				
			||||||
    notification_service.update_team_member(self) if self.project_access_changed?
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def post_destroy_hook
 | 
					 | 
				
			||||||
    Event.create(
 | 
					 | 
				
			||||||
      project_id: self.project.id,
 | 
					 | 
				
			||||||
      action: Event::LEFT,
 | 
					 | 
				
			||||||
      author_id: self.user.id
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    system_hook_service.execute_hooks_for(self, :destroy)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def notification_service
 | 
					 | 
				
			||||||
    NotificationService.new
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def system_hook_service
 | 
					 | 
				
			||||||
    SystemHooksService.new
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
| 
						 | 
					@ -157,12 +157,12 @@ class NotificationService
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def new_team_member(users_project)
 | 
					  def new_team_member(project_member)
 | 
				
			||||||
    mailer.project_access_granted_email(users_project.id)
 | 
					    mailer.project_access_granted_email(project_member.id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def update_team_member(users_project)
 | 
					  def update_team_member(project_member)
 | 
				
			||||||
    mailer.project_access_granted_email(users_project.id)
 | 
					    mailer.project_access_granted_email(project_member.id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def new_group_member(users_group)
 | 
					  def new_group_member(users_group)
 | 
				
			||||||
| 
						 | 
					@ -186,20 +186,20 @@ class NotificationService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Get project users with WATCH notification level
 | 
					  # Get project users with WATCH notification level
 | 
				
			||||||
  def project_watchers(project)
 | 
					  def project_watchers(project)
 | 
				
			||||||
    project_members = users_project_notification(project)
 | 
					    project_members = project_member_notification(project)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    users_with_project_level_global = users_project_notification(project, Notification::N_GLOBAL)
 | 
					    users_with_project_level_global = project_member_notification(project, Notification::N_GLOBAL)
 | 
				
			||||||
    users_with_group_level_global = users_group_notification(project, Notification::N_GLOBAL)
 | 
					    users_with_group_level_global = users_group_notification(project, Notification::N_GLOBAL)
 | 
				
			||||||
    users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq)
 | 
					    users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    users_with_project_setting = select_users_project_setting(project, users_with_project_level_global, users)
 | 
					    users_with_project_setting = select_project_member_setting(project, users_with_project_level_global, users)
 | 
				
			||||||
    users_with_group_setting = select_users_group_setting(project, project_members, users_with_group_level_global, users)
 | 
					    users_with_group_setting = select_users_group_setting(project, project_members, users_with_group_level_global, users)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    User.where(id: users_with_project_setting.concat(users_with_group_setting).uniq).to_a
 | 
					    User.where(id: users_with_project_setting.concat(users_with_group_setting).uniq).to_a
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def users_project_notification(project, notification_level=nil)
 | 
					  def project_member_notification(project, notification_level=nil)
 | 
				
			||||||
    project_members = project.users_projects
 | 
					    project_members = project.project_members
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if notification_level
 | 
					    if notification_level
 | 
				
			||||||
      project_members.where(notification_level: notification_level).pluck(:user_id)
 | 
					      project_members.where(notification_level: notification_level).pluck(:user_id)
 | 
				
			||||||
| 
						 | 
					@ -210,7 +210,7 @@ class NotificationService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def users_group_notification(project, notification_level)
 | 
					  def users_group_notification(project, notification_level)
 | 
				
			||||||
    if project.group
 | 
					    if project.group
 | 
				
			||||||
      project.group.users_groups.where(notification_level: notification_level).pluck(:user_id)
 | 
					      project.group.group_members.where(notification_level: notification_level).pluck(:user_id)
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      []
 | 
					      []
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					@ -224,8 +224,8 @@ class NotificationService
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Build a list of users based on project notifcation settings
 | 
					  # Build a list of users based on project notifcation settings
 | 
				
			||||||
  def select_users_project_setting(project, global_setting, users_global_level_watch)
 | 
					  def select_project_member_setting(project, global_setting, users_global_level_watch)
 | 
				
			||||||
    users = users_project_notification(project, Notification::N_WATCH)
 | 
					    users = project_member_notification(project, Notification::N_WATCH)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # If project setting is global, add to watch list if global setting is watch
 | 
					    # If project setting is global, add to watch list if global setting is watch
 | 
				
			||||||
    global_setting.each do |user_id|
 | 
					    global_setting.each do |user_id|
 | 
				
			||||||
| 
						 | 
					@ -267,10 +267,10 @@ class NotificationService
 | 
				
			||||||
    users.reject do |user|
 | 
					    users.reject do |user|
 | 
				
			||||||
      next user.notification.disabled? unless project
 | 
					      next user.notification.disabled? unless project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      tm = project.users_projects.find_by(user_id: user.id)
 | 
					      tm = project.project_members.find_by(user_id: user.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if !tm && project.group
 | 
					      if !tm && project.group
 | 
				
			||||||
        tm = project.group.users_groups.find_by(user_id: user.id)
 | 
					        tm = project.group.group_members.find_by(user_id: user.id)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # reject users who globally disabled notification and has no membership
 | 
					      # reject users who globally disabled notification and has no membership
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,10 +42,7 @@ module Projects
 | 
				
			||||||
        system_hook_service.execute_hooks_for(@project, :create)
 | 
					        system_hook_service.execute_hooks_for(@project, :create)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unless @project.group
 | 
					        unless @project.group
 | 
				
			||||||
          @project.users_projects.create(
 | 
					          @project.team << [current_user, :master]
 | 
				
			||||||
            project_access: UsersProject::MASTER,
 | 
					 | 
				
			||||||
            user: current_user
 | 
					 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @project.update_column(:last_activity_at, @project.created_at)
 | 
					        @project.update_column(:last_activity_at, @project.created_at)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ module Projects
 | 
				
			||||||
            #First save the DB entries as they can be rolled back if the repo fork fails
 | 
					            #First save the DB entries as they can be rolled back if the repo fork fails
 | 
				
			||||||
            project.build_forked_project_link(forked_to_project_id: project.id, forked_from_project_id: @from_project.id)
 | 
					            project.build_forked_project_link(forked_to_project_id: project.id, forked_from_project_id: @from_project.id)
 | 
				
			||||||
            if project.save
 | 
					            if project.save
 | 
				
			||||||
              project.users_projects.create(project_access: UsersProject::MASTER, user: current_user)
 | 
					              project.team << [current_user, :master]
 | 
				
			||||||
            end
 | 
					            end
 | 
				
			||||||
            #Now fork the repo
 | 
					            #Now fork the repo
 | 
				
			||||||
            unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
 | 
					            unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,14 +50,14 @@ class SystemHooksService
 | 
				
			||||||
        email: model.email,
 | 
					        email: model.email,
 | 
				
			||||||
        user_id: model.id
 | 
					        user_id: model.id
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    when UsersProject
 | 
					    when ProjectMember
 | 
				
			||||||
      data.merge!({
 | 
					      data.merge!({
 | 
				
			||||||
        project_name: model.project.name,
 | 
					        project_name: model.project.name,
 | 
				
			||||||
        project_path: model.project.path,
 | 
					        project_path: model.project.path,
 | 
				
			||||||
        project_id: model.project_id,
 | 
					        project_id: model.project.id,
 | 
				
			||||||
        user_name: model.user.name,
 | 
					        user_name: model.user.name,
 | 
				
			||||||
        user_email: model.user.email,
 | 
					        user_email: model.user.email,
 | 
				
			||||||
        project_access: model.human_access,
 | 
					        access_level: model.human_access,
 | 
				
			||||||
        project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase
 | 
					        project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ class SystemHooksService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def build_event_name(model, event)
 | 
					  def build_event_name(model, event)
 | 
				
			||||||
    case model
 | 
					    case model
 | 
				
			||||||
    when UsersProject
 | 
					    when ProjectMember
 | 
				
			||||||
      return "user_add_to_team"      if event == :create
 | 
					      return "user_add_to_team"      if event == :create
 | 
				
			||||||
      return "user_remove_from_team" if event == :destroy
 | 
					      return "user_remove_from_team" if event == :destroy
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@
 | 
				
			||||||
          %div
 | 
					          %div
 | 
				
			||||||
            = users_select_tag(:user_ids, multiple: true)
 | 
					            = users_select_tag(:user_ids, multiple: true)
 | 
				
			||||||
          %div.prepend-top-10
 | 
					          %div.prepend-top-10
 | 
				
			||||||
            = select_tag :group_access, options_for_select(UsersGroup.group_access_roles), class: "project-access-select select2"
 | 
					            = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2"
 | 
				
			||||||
          %hr
 | 
					          %hr
 | 
				
			||||||
          = submit_tag 'Add users into group', class: "btn btn-create"
 | 
					          = submit_tag 'Add users into group', class: "btn btn-create"
 | 
				
			||||||
    .panel.panel-default
 | 
					    .panel.panel-default
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@
 | 
				
			||||||
        %h3.panel-title
 | 
					        %h3.panel-title
 | 
				
			||||||
          Members
 | 
					          Members
 | 
				
			||||||
          %span.badge
 | 
					          %span.badge
 | 
				
			||||||
            #{@group.users_groups.count}
 | 
					            #{@group.group_members.count}
 | 
				
			||||||
      %ul.well-list.group-users-list
 | 
					      %ul.well-list.group-users-list
 | 
				
			||||||
        - @members.each do |member|
 | 
					        - @members.each do |member|
 | 
				
			||||||
          - user = member.user
 | 
					          - user = member.user
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@
 | 
				
			||||||
                = 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), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
 | 
					              = link_to group_group_members_path(@group, member), data: { 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
 | 
					                %i.icon-minus.icon-white
 | 
				
			||||||
      .panel-footer
 | 
					      .panel-footer
 | 
				
			||||||
        = paginate @members, param_name: 'members_page', theme: 'gitlab'
 | 
					        = paginate @members, param_name: 'members_page', theme: 'gitlab'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,13 +95,13 @@
 | 
				
			||||||
      .panel.panel-default
 | 
					      .panel.panel-default
 | 
				
			||||||
        .panel-heading
 | 
					        .panel-heading
 | 
				
			||||||
          %strong #{@group.name}
 | 
					          %strong #{@group.name}
 | 
				
			||||||
          group members (#{@group.users_groups.count})
 | 
					          group members (#{@group.group_members.count})
 | 
				
			||||||
          .pull-right
 | 
					          .pull-right
 | 
				
			||||||
            = link_to admin_group_path(@group), class: 'btn btn-small' do
 | 
					            = link_to admin_group_path(@group), class: 'btn btn-small' do
 | 
				
			||||||
              %i.icon-edit
 | 
					              %i.icon-edit
 | 
				
			||||||
        %ul.well-list
 | 
					        %ul.well-list
 | 
				
			||||||
          - @group_members.each do |member|
 | 
					          - @group_members.each do |member|
 | 
				
			||||||
            = render 'users_groups/users_group', member: member, show_controls: false
 | 
					            = render 'groups/group_members/group_member', member: member, show_controls: false
 | 
				
			||||||
        .panel-footer
 | 
					        .panel-footer
 | 
				
			||||||
          = paginate @group_members, param_name: 'group_members_page', theme: 'gitlab'
 | 
					          = paginate @group_members, param_name: 'group_members_page', theme: 'gitlab'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,17 +115,17 @@
 | 
				
			||||||
            %i.icon-edit
 | 
					            %i.icon-edit
 | 
				
			||||||
            Manage Access
 | 
					            Manage Access
 | 
				
			||||||
      %ul.well-list.team_members
 | 
					      %ul.well-list.team_members
 | 
				
			||||||
        - @project_members.each do |users_project|
 | 
					        - @project_members.each do |project_member|
 | 
				
			||||||
          - user = users_project.user
 | 
					          - user = project_member.user
 | 
				
			||||||
          %li.users_project
 | 
					          %li.project_member
 | 
				
			||||||
            .list-item-name
 | 
					            .list-item-name
 | 
				
			||||||
              %strong
 | 
					              %strong
 | 
				
			||||||
                = link_to user.name, admin_user_path(user)
 | 
					                = link_to user.name, admin_user_path(user)
 | 
				
			||||||
            .pull-right
 | 
					            .pull-right
 | 
				
			||||||
              - if users_project.owner?
 | 
					              - if project_member.owner?
 | 
				
			||||||
                %span.light Owner
 | 
					                %span.light Owner
 | 
				
			||||||
              - else
 | 
					              - else
 | 
				
			||||||
                %span.light= users_project.human_access
 | 
					                %span.light= project_member.human_access
 | 
				
			||||||
                = link_to project_team_member_path(@project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-small btn-remove" do
 | 
					                = link_to project_team_member_path(@project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-small btn-remove" do
 | 
				
			||||||
                  %i.icon-remove
 | 
					                  %i.icon-remove
 | 
				
			||||||
      .panel-footer
 | 
					      .panel-footer
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,13 +159,13 @@
 | 
				
			||||||
        = render 'users/profile', user: @user
 | 
					        = render 'users/profile', user: @user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #groups.tab-pane
 | 
					  #groups.tab-pane
 | 
				
			||||||
    - if @user.users_groups.present?
 | 
					    - if @user.group_members.present?
 | 
				
			||||||
      .panel.panel-default
 | 
					      .panel.panel-default
 | 
				
			||||||
        .panel-heading Groups:
 | 
					        .panel-heading Groups:
 | 
				
			||||||
        %ul.well-list
 | 
					        %ul.well-list
 | 
				
			||||||
          - @user.users_groups.each do |user_group|
 | 
					          - @user.group_members.each do |user_group|
 | 
				
			||||||
            - group = user_group.group
 | 
					            - group = user_group.group
 | 
				
			||||||
            %li.users_group
 | 
					            %li.group_member
 | 
				
			||||||
              %span{class: ("list-item-name" unless user_group.owner?)}
 | 
					              %span{class: ("list-item-name" unless user_group.owner?)}
 | 
				
			||||||
                %strong= link_to group.name, admin_group_path(group)
 | 
					                %strong= link_to group.name, admin_group_path(group)
 | 
				
			||||||
              .pull-right
 | 
					              .pull-right
 | 
				
			||||||
| 
						 | 
					@ -197,7 +197,7 @@
 | 
				
			||||||
          %ul.well-list
 | 
					          %ul.well-list
 | 
				
			||||||
            - @joined_projects.sort_by(&:name_with_namespace).each do |project|
 | 
					            - @joined_projects.sort_by(&:name_with_namespace).each do |project|
 | 
				
			||||||
              - tm = project.team.find_tm(@user.id)
 | 
					              - tm = project.team.find_tm(@user.id)
 | 
				
			||||||
              %li.users_project
 | 
					              %li.project_member
 | 
				
			||||||
                .list-item-name
 | 
					                .list-item-name
 | 
				
			||||||
                  = link_to admin_project_path(project), class: dom_class(project) do
 | 
					                  = link_to admin_project_path(project), class: dom_class(project) do
 | 
				
			||||||
                    = project.name_with_namespace
 | 
					                    = project.name_with_namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
= form_for @users_group, url: group_users_groups_path(@group), html: { class: 'form-horizontal users-group-form' } do |f|
 | 
					= form_for @users_group, url: group_group_members_path(@group), html: { class: 'form-horizontal users-group-form' } do |f|
 | 
				
			||||||
  .form-group
 | 
					  .form-group
 | 
				
			||||||
    = f.label :user_ids, "People", class: 'control-label'
 | 
					    = f.label :user_ids, "People", class: 'control-label'
 | 
				
			||||||
    .col-sm-10= users_select_tag(:user_ids, multiple: true, class: 'input-large')
 | 
					    .col-sm-10= users_select_tag(:user_ids, multiple: true, class: 'input-large')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .form-group
 | 
					  .form-group
 | 
				
			||||||
    = f.label :group_access, "Group Access", class: 'control-label'
 | 
					    = f.label :access_level, "Group Access", class: 'control-label'
 | 
				
			||||||
    .col-sm-10= select_tag :group_access, options_for_select(UsersGroup.group_access_roles, @users_group.group_access), class: "project-access-select select2"
 | 
					    .col-sm-10= select_tag :access_level, options_for_select(GroupMember.access_level_roles, @users_group.access_level), class: "project-access-select select2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .form-actions
 | 
					  .form-actions
 | 
				
			||||||
    = f.submit 'Add users into group', class: "btn btn-create"
 | 
					    = f.submit 'Add users into group', class: "btn btn-create"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,11 +21,11 @@
 | 
				
			||||||
            = link_to leave_profile_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
 | 
					            = link_to leave_profile_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
 | 
				
			||||||
              %i.icon-minus.icon-white
 | 
					              %i.icon-minus.icon-white
 | 
				
			||||||
          - else
 | 
					          - else
 | 
				
			||||||
            = link_to group_users_group_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
 | 
					            = link_to group_group_member_path(@group, member), data: { 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
 | 
					              %i.icon-minus.icon-white
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .edit-member.hide.js-toggle-content
 | 
					    .edit-member.hide.js-toggle-content
 | 
				
			||||||
      = form_for [@group, member], remote: true do |f|
 | 
					      = form_for [@group, member], remote: true do |f|
 | 
				
			||||||
        .alert.prepend-top-20
 | 
					        .alert.prepend-top-20
 | 
				
			||||||
          = f.select :group_access, options_for_select(UsersGroup.group_access_roles, member.group_access)
 | 
					          = f.select :access_level, options_for_select(GroupMember.access_level_roles, member.access_level)
 | 
				
			||||||
          = f.submit 'Save', class: 'btn btn-save btn-small'
 | 
					          = f.submit 'Save', class: 'btn btn-save btn-small'
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@
 | 
				
			||||||
      (#{@members.total_count})
 | 
					      (#{@members.total_count})
 | 
				
			||||||
  %ul.well-list
 | 
					  %ul.well-list
 | 
				
			||||||
    - @members.each do |member|
 | 
					    - @members.each do |member|
 | 
				
			||||||
      = render 'users_groups/users_group', member: member, show_roles: show_roles, show_controls: true
 | 
					      = render 'groups/group_members/group_member', member: member, show_roles: show_roles, show_controls: true
 | 
				
			||||||
= paginate @members, theme: 'gitlab'
 | 
					= paginate @members, theme: 'gitlab'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:coffeescript
 | 
					:coffeescript
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
%p
 | 
					%p
 | 
				
			||||||
  = "You have been granted #{@users_project.human_access} access to project"
 | 
					  = "You have been granted #{@project_member.human_access} access to project"
 | 
				
			||||||
%p
 | 
					%p
 | 
				
			||||||
  = link_to project_url(@project) do
 | 
					  = link_to project_url(@project) do
 | 
				
			||||||
    = @project.name_with_namespace
 | 
					    = @project.name_with_namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You have been granted <%= @users_project.human_access %> access to project <%= @project.name_with_namespace %>
 | 
					You have been granted <%= @project_member.human_access %> access to project <%= @project.name_with_namespace %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<%= url_for(project_url(@project)) %>
 | 
					<%= url_for(project_url(@project)) %>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@
 | 
				
			||||||
      = notification_icon(notification)
 | 
					      = notification_icon(notification)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  %span.str-truncated
 | 
					  %span.str-truncated
 | 
				
			||||||
    - if membership.kind_of? UsersGroup
 | 
					    - if membership.kind_of? GroupMember
 | 
				
			||||||
      = link_to membership.group.name, membership.group
 | 
					      = link_to membership.group.name, membership.group
 | 
				
			||||||
    - else
 | 
					    - else
 | 
				
			||||||
      = link_to_project(membership.project)
 | 
					      = link_to_project(membership.project)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,13 +39,13 @@
 | 
				
			||||||
  .col-md-6
 | 
					  .col-md-6
 | 
				
			||||||
    %h4 Groups:
 | 
					    %h4 Groups:
 | 
				
			||||||
    %ul.bordered-list
 | 
					    %ul.bordered-list
 | 
				
			||||||
      - @users_groups.each do |users_group|
 | 
					      - @group_members.each do |users_group|
 | 
				
			||||||
        - notification = Notification.new(users_group)
 | 
					        - notification = Notification.new(users_group)
 | 
				
			||||||
        = render 'settings', type: 'group', membership: users_group, notification: notification
 | 
					        = render 'settings', type: 'group', membership: users_group, notification: notification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .col-md-6
 | 
					  .col-md-6
 | 
				
			||||||
    %h4 Projects:
 | 
					    %h4 Projects:
 | 
				
			||||||
    %ul.bordered-list
 | 
					    %ul.bordered-list
 | 
				
			||||||
      - @users_projects.each do |users_project|
 | 
					      - @project_members.each do |project_member|
 | 
				
			||||||
        - notification = Notification.new(users_project)
 | 
					        - notification = Notification.new(project_member)
 | 
				
			||||||
        = render 'settings', type: 'project', membership: users_project, notification: notification
 | 
					        = render 'settings', type: 'project', membership: project_member, notification: notification
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
%h3.page-title
 | 
					%h3.page-title
 | 
				
			||||||
  New project member(s)
 | 
					  New project member(s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
= form_for @user_project_relation, as: :team_member, url: project_team_members_path(@project), html: { class: "form-horizontal users-project-form" } do |f|
 | 
					= form_for @user_project_relation, as: :project_member, url: project_team_members_path(@project), html: { class: "form-horizontal users-project-form" } do |f|
 | 
				
			||||||
  -if @user_project_relation.errors.any?
 | 
					  -if @user_project_relation.errors.any?
 | 
				
			||||||
    .alert.alert-danger
 | 
					    .alert.alert-danger
 | 
				
			||||||
      %ul
 | 
					      %ul
 | 
				
			||||||
| 
						 | 
					@ -16,8 +16,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  %p 2. Set access level for them
 | 
					  %p 2. Set access level for them
 | 
				
			||||||
  .form-group
 | 
					  .form-group
 | 
				
			||||||
    = f.label :project_access, "Project Access", class: 'control-label'
 | 
					    = f.label :access_level, "Project Access", class: 'control-label'
 | 
				
			||||||
    .col-sm-10= select_tag :project_access, options_for_select(Gitlab::Access.options, @user_project_relation.project_access), class: "project-access-select select2"
 | 
					    .col-sm-10= select_tag :access_level, options_for_select(Gitlab::Access.options, @user_project_relation.access_level), class: "project-access-select select2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .form-actions
 | 
					  .form-actions
 | 
				
			||||||
    = f.submit 'Add users', class: "btn btn-create"
 | 
					    = f.submit 'Add users', class: "btn btn-create"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
- group_users_count = @group.users_groups.count
 | 
					- group_users_count = @group.group_members.count
 | 
				
			||||||
.panel.panel-default
 | 
					.panel.panel-default
 | 
				
			||||||
  .panel-heading
 | 
					  .panel-heading
 | 
				
			||||||
    %strong #{@group.name}
 | 
					    %strong #{@group.name}
 | 
				
			||||||
| 
						 | 
					@ -7,8 +7,8 @@
 | 
				
			||||||
      = link_to members_group_path(@group), class: 'btn btn-small' do
 | 
					      = link_to members_group_path(@group), class: 'btn btn-small' do
 | 
				
			||||||
        %i.icon-edit
 | 
					        %i.icon-edit
 | 
				
			||||||
  %ul.well-list
 | 
					  %ul.well-list
 | 
				
			||||||
    - @group.users_groups.order('group_access DESC').limit(20).each do |member|
 | 
					    - @group.group_members.order('access_level DESC').limit(20).each do |member|
 | 
				
			||||||
      = render 'users_groups/users_group', member: member, show_controls: false
 | 
					      = render 'groups/group_members/group_member', member: member, show_controls: false
 | 
				
			||||||
    - if group_users_count > 20
 | 
					    - if group_users_count > 20
 | 
				
			||||||
      %li
 | 
					      %li
 | 
				
			||||||
        and #{group_users_count - 20} more. For full list visit #{link_to 'group members page', members_group_path(@group)}
 | 
					        and #{group_users_count - 20} more. For full list visit #{link_to 'group members page', members_group_path(@group)}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,8 +4,8 @@
 | 
				
			||||||
    - if current_user_can_admin_project
 | 
					    - if current_user_can_admin_project
 | 
				
			||||||
      - unless @project.personal? && user == current_user
 | 
					      - unless @project.personal? && user == current_user
 | 
				
			||||||
        .pull-left
 | 
					        .pull-left
 | 
				
			||||||
          = form_for(member, as: :team_member, url: project_team_member_path(@project, member.user)) do |f|
 | 
					          = form_for(member, as: :project_member, url: project_team_member_path(@project, member.user)) do |f|
 | 
				
			||||||
            = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2 trigger-submit"
 | 
					            = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: "medium project-access-select span2 trigger-submit"
 | 
				
			||||||
           
 | 
					           
 | 
				
			||||||
        = link_to project_team_member_path(@project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do
 | 
					        = link_to project_team_member_path(@project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do
 | 
				
			||||||
          %i.icon-minus.icon-white
 | 
					          %i.icon-minus.icon-white
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,6 @@
 | 
				
			||||||
%p.light
 | 
					%p.light
 | 
				
			||||||
  Read more about project permissions
 | 
					  Read more about project permissions
 | 
				
			||||||
  %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
 | 
					  %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
 | 
				
			||||||
= render "team", members: @users_projects
 | 
					= render "team", members: @project_members
 | 
				
			||||||
- if @group
 | 
					- if @group
 | 
				
			||||||
  = render "group_members"
 | 
					  = render "group_members"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,12 @@ module Gitlab
 | 
				
			||||||
    # -- all .rb files in that directory are automatically loaded.
 | 
					    # -- all .rb files in that directory are automatically loaded.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Custom directories with classes and modules you want to be autoloadable.
 | 
					    # Custom directories with classes and modules you want to be autoloadable.
 | 
				
			||||||
    config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/finders #{config.root}/app/models/concerns #{config.root}/app/models/project_services)
 | 
					    config.autoload_paths += %W(#{config.root}/lib
 | 
				
			||||||
 | 
					                                #{config.root}/app/finders
 | 
				
			||||||
 | 
					                                #{config.root}/app/models/hooks
 | 
				
			||||||
 | 
					                                #{config.root}/app/models/concerns
 | 
				
			||||||
 | 
					                                #{config.root}/app/models/project_services
 | 
				
			||||||
 | 
					                                #{config.root}/app/models/members)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Only load the plugins named here, in the order given (default is alphabetical).
 | 
					    # Only load the plugins named here, in the order given (default is alphabetical).
 | 
				
			||||||
    # :all can be used as a placeholder for all plugins not explicitly named.
 | 
					    # :all can be used as a placeholder for all plugins not explicitly named.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,9 +161,8 @@ Gitlab::Application.routes.draw do
 | 
				
			||||||
      get :projects
 | 
					      get :projects
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resources :users_groups, only: [:create, :update, :destroy]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    scope module: :groups do
 | 
					    scope module: :groups do
 | 
				
			||||||
 | 
					      resources :group_members, only: [:create, :update, :destroy]
 | 
				
			||||||
      resource :avatar, only: [:destroy]
 | 
					      resource :avatar, only: [:destroy]
 | 
				
			||||||
      resources :milestones
 | 
					      resources :milestones
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,5 +10,10 @@ class AddMembersTable < ActiveRecord::Migration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      t.timestamps
 | 
					      t.timestamps
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_index :members, :type
 | 
				
			||||||
 | 
					    add_index :members, :user_id
 | 
				
			||||||
 | 
					    add_index :members, :access_level
 | 
				
			||||||
 | 
					    add_index :members, [:source_id, :source_type]
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					class MigrateToNewMembersModel < ActiveRecord::Migration
 | 
				
			||||||
 | 
					  def up
 | 
				
			||||||
 | 
					    execute "INSERT INTO members ( user_id, source_id, source_type, access_level, notification_level, type ) SELECT user_id, group_id, 'Namespace', group_access, notification_level, 'GroupMember' FROM users_groups"
 | 
				
			||||||
 | 
					    execute "INSERT INTO members ( user_id, source_id, source_type, access_level, notification_level, type ) SELECT user_id, project_id, 'Project', project_access, notification_level, 'ProjectMember' FROM users_projects"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def down
 | 
				
			||||||
 | 
					    Member.delete_all
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
class MigrateToNewmembersModel < ActiveRecord::Migration
 | 
					 | 
				
			||||||
  def up
 | 
					 | 
				
			||||||
    UsersGroup.find_each(batch_size: 500) do |user_group|
 | 
					 | 
				
			||||||
      GroupMember.create(
 | 
					 | 
				
			||||||
        user_id: user_group.user_id,
 | 
					 | 
				
			||||||
        source_type: 'Group',
 | 
					 | 
				
			||||||
        source_id: user_group.group_id,
 | 
					 | 
				
			||||||
        access_level: user_group.group_access,
 | 
					 | 
				
			||||||
        notification_level: user_group.notification_level,
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      print '.'
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    UsersProject.find_each(batch_size: 500) do |user_project|
 | 
					 | 
				
			||||||
      ProjectMember.create(
 | 
					 | 
				
			||||||
        user_id: user_project.user_id,
 | 
					 | 
				
			||||||
        source_type: 'Project',
 | 
					 | 
				
			||||||
        source_id: user_project.project_id,
 | 
					 | 
				
			||||||
        access_level: user_project.project_access,
 | 
					 | 
				
			||||||
        notification_level: user_project.notification_level,
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      print '.'
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def down
 | 
					 | 
				
			||||||
    Member.destroy_all
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					class RemoveOldMemberTables < ActiveRecord::Migration
 | 
				
			||||||
 | 
					  def up
 | 
				
			||||||
 | 
					    drop_table :users_groups
 | 
				
			||||||
 | 
					    drop_table :users_projects
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def down
 | 
				
			||||||
 | 
					    create_table :users_groups do |t|
 | 
				
			||||||
 | 
					      t.integer :group_access, null: false
 | 
				
			||||||
 | 
					      t.integer :group_id, null: false
 | 
				
			||||||
 | 
					      t.integer :user_id, null: false
 | 
				
			||||||
 | 
					      t.integer :notification_level, null: false, default: 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      t.timestamps
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    create_table :users_projects do |t|
 | 
				
			||||||
 | 
					      t.integer :project_access, null: false
 | 
				
			||||||
 | 
					      t.integer :project_id, null: false
 | 
				
			||||||
 | 
					      t.integer :user_id, null: false
 | 
				
			||||||
 | 
					      t.integer :notification_level, null: false, default: 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      t.timestamps
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										31
									
								
								db/schema.rb
								
								
								
								
							
							
						
						
									
										31
									
								
								db/schema.rb
								
								
								
								
							| 
						 | 
					@ -11,7 +11,7 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# It's strongly recommended that you check this file into your version control system.
 | 
					# It's strongly recommended that you check this file into your version control system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActiveRecord::Schema.define(version: 20140914145549) do
 | 
					ActiveRecord::Schema.define(version: 20140914173417) do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # These are extensions that must be enabled in order to support this database
 | 
					  # These are extensions that must be enabled in order to support this database
 | 
				
			||||||
  enable_extension "plpgsql"
 | 
					  enable_extension "plpgsql"
 | 
				
			||||||
| 
						 | 
					@ -141,6 +141,11 @@ ActiveRecord::Schema.define(version: 20140914145549) do
 | 
				
			||||||
    t.datetime "updated_at"
 | 
					    t.datetime "updated_at"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  add_index "members", ["access_level"], name: "index_members_on_access_level", using: :btree
 | 
				
			||||||
 | 
					  add_index "members", ["source_id", "source_type"], name: "index_members_on_source_id_and_source_type", using: :btree
 | 
				
			||||||
 | 
					  add_index "members", ["type"], name: "index_members_on_type", using: :btree
 | 
				
			||||||
 | 
					  add_index "members", ["user_id"], name: "index_members_on_user_id", using: :btree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create_table "merge_request_diffs", force: true do |t|
 | 
					  create_table "merge_request_diffs", force: true do |t|
 | 
				
			||||||
    t.string   "state"
 | 
					    t.string   "state"
 | 
				
			||||||
    t.text     "st_commits"
 | 
					    t.text     "st_commits"
 | 
				
			||||||
| 
						 | 
					@ -374,30 +379,6 @@ ActiveRecord::Schema.define(version: 20140914145549) do
 | 
				
			||||||
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
 | 
					  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
 | 
				
			||||||
  add_index "users", ["username"], name: "index_users_on_username", using: :btree
 | 
					  add_index "users", ["username"], name: "index_users_on_username", using: :btree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create_table "users_groups", force: true do |t|
 | 
					 | 
				
			||||||
    t.integer  "group_access",                   null: false
 | 
					 | 
				
			||||||
    t.integer  "group_id",                       null: false
 | 
					 | 
				
			||||||
    t.integer  "user_id",                        null: false
 | 
					 | 
				
			||||||
    t.datetime "created_at"
 | 
					 | 
				
			||||||
    t.datetime "updated_at"
 | 
					 | 
				
			||||||
    t.integer  "notification_level", default: 3, null: false
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  add_index "users_groups", ["user_id"], name: "index_users_groups_on_user_id", using: :btree
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  create_table "users_projects", force: true do |t|
 | 
					 | 
				
			||||||
    t.integer  "user_id",                        null: false
 | 
					 | 
				
			||||||
    t.integer  "project_id",                     null: false
 | 
					 | 
				
			||||||
    t.datetime "created_at"
 | 
					 | 
				
			||||||
    t.datetime "updated_at"
 | 
					 | 
				
			||||||
    t.integer  "project_access",     default: 0, null: false
 | 
					 | 
				
			||||||
    t.integer  "notification_level", default: 3, null: false
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  add_index "users_projects", ["project_access"], name: "index_users_projects_on_project_access", using: :btree
 | 
					 | 
				
			||||||
  add_index "users_projects", ["project_id"], name: "index_users_projects_on_project_id", using: :btree
 | 
					 | 
				
			||||||
  add_index "users_projects", ["user_id"], name: "index_users_projects_on_user_id", using: :btree
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  create_table "users_star_projects", force: true do |t|
 | 
					  create_table "users_star_projects", force: true do |t|
 | 
				
			||||||
    t.integer  "project_id", null: false
 | 
					    t.integer  "project_id", null: false
 | 
				
			||||||
    t.integer  "user_id",    null: false
 | 
					    t.integer  "user_id",    null: false
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@ class AdminGroups < Spinach::FeatureSteps
 | 
				
			||||||
    user = User.find_by(name: "John Doe")
 | 
					    user = User.find_by(name: "John Doe")
 | 
				
			||||||
    select2(user.id, from: "#user_ids", multiple: true)
 | 
					    select2(user.id, from: "#user_ids", multiple: true)
 | 
				
			||||||
    within "#new_team_member" do
 | 
					    within "#new_team_member" do
 | 
				
			||||||
      select "Reporter", from: "group_access"
 | 
					      select "Reporter", from: "access_level"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    click_button "Add users into group"
 | 
					    click_button "Add users into group"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ class Groups < Spinach::FeatureSteps
 | 
				
			||||||
    click_link 'Add members'
 | 
					    click_link 'Add members'
 | 
				
			||||||
    within ".users-group-form" do
 | 
					    within ".users-group-form" do
 | 
				
			||||||
      select2(user.id, from: "#user_ids", multiple: true)
 | 
					      select2(user.id, from: "#user_ids", multiple: true)
 | 
				
			||||||
      select "Reporter", from: "group_access"
 | 
					      select "Reporter", from: "access_level"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    click_button "Add users into group"
 | 
					    click_button "Add users into group"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,8 +23,8 @@ class ProjectTeamManagement < Spinach::FeatureSteps
 | 
				
			||||||
    user = User.find_by(name: "Mike")
 | 
					    user = User.find_by(name: "Mike")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    select2(user.id, from: "#user_ids", multiple: true)
 | 
					    select2(user.id, from: "#user_ids", multiple: true)
 | 
				
			||||||
    within "#new_team_member" do
 | 
					    within "#new_project_member" do
 | 
				
			||||||
      select "Reporter", from: "project_access"
 | 
					      select "Reporter", from: "access_level"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    click_button "Add users"
 | 
					    click_button "Add users"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps
 | 
				
			||||||
  And 'I change "Sam" role to "Reporter"' do
 | 
					  And 'I change "Sam" role to "Reporter"' do
 | 
				
			||||||
    user = User.find_by(name: "Sam")
 | 
					    user = User.find_by(name: "Sam")
 | 
				
			||||||
    within "#user_#{user.id}" do
 | 
					    within "#user_#{user.id}" do
 | 
				
			||||||
      select "Reporter", from: "team_member_project_access"
 | 
					      select "Reporter", from: "project_member_access_level"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,8 +53,8 @@ module API
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class ProjectMember < UserBasic
 | 
					    class ProjectMember < UserBasic
 | 
				
			||||||
      expose :project_access, as: :access_level do |user, options|
 | 
					      expose :access_level do |user, options|
 | 
				
			||||||
        options[:project].users_projects.find_by(user_id: user.id).project_access
 | 
					        options[:project].project_members.find_by(user_id: user.id).access_level
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,8 +67,8 @@ module API
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class GroupMember < UserBasic
 | 
					    class GroupMember < UserBasic
 | 
				
			||||||
      expose :group_access, as: :access_level do |user, options|
 | 
					      expose :access_level do |user, options|
 | 
				
			||||||
        options[:group].users_groups.find_by(user_id: user.id).group_access
 | 
					        options[:group].group_members.find_by(user_id: user.id).access_level
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,24 +170,24 @@ module API
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class ProjectAccess < Grape::Entity
 | 
					    class ProjectAccess < Grape::Entity
 | 
				
			||||||
      expose :project_access, as: :access_level
 | 
					      expose :access_level
 | 
				
			||||||
      expose :notification_level
 | 
					      expose :notification_level
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class GroupAccess < Grape::Entity
 | 
					    class GroupAccess < Grape::Entity
 | 
				
			||||||
      expose :group_access, as: :access_level
 | 
					      expose :access_level
 | 
				
			||||||
      expose :notification_level
 | 
					      expose :notification_level
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class ProjectWithAccess < Project
 | 
					    class ProjectWithAccess < Project
 | 
				
			||||||
      expose :permissions do
 | 
					      expose :permissions do
 | 
				
			||||||
        expose :project_access, using: Entities::ProjectAccess do |project, options|
 | 
					        expose :project_access, using: Entities::ProjectAccess do |project, options|
 | 
				
			||||||
          project.users_projects.find_by(user_id: options[:user].id)
 | 
					          project.project_members.find_by(user_id: options[:user].id)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expose :group_access, using: Entities::GroupAccess do |project, options|
 | 
					        expose :group_access, using: Entities::GroupAccess do |project, options|
 | 
				
			||||||
          if project.group
 | 
					          if project.group
 | 
				
			||||||
            project.group.users_groups.find_by(user_id: options[:user].id)
 | 
					            project.group.group_members.find_by(user_id: options[:user].id)
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,7 +104,7 @@ module API
 | 
				
			||||||
      #  GET /groups/:id/members
 | 
					      #  GET /groups/:id/members
 | 
				
			||||||
      get ":id/members" do
 | 
					      get ":id/members" do
 | 
				
			||||||
        group = find_group(params[:id])
 | 
					        group = find_group(params[:id])
 | 
				
			||||||
        members = group.users_groups
 | 
					        members = group.group_members
 | 
				
			||||||
        users = (paginate members).collect(&:user)
 | 
					        users = (paginate members).collect(&:user)
 | 
				
			||||||
        present users, with: Entities::GroupMember, group: group
 | 
					        present users, with: Entities::GroupMember, group: group
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
| 
						 | 
					@ -123,11 +123,11 @@ module API
 | 
				
			||||||
          render_api_error!("Wrong access level", 422)
 | 
					          render_api_error!("Wrong access level", 422)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
        group = find_group(params[:id])
 | 
					        group = find_group(params[:id])
 | 
				
			||||||
        if group.users_groups.find_by(user_id: params[:user_id])
 | 
					        if group.group_members.find_by(user_id: params[:user_id])
 | 
				
			||||||
          render_api_error!("Already exists", 409)
 | 
					          render_api_error!("Already exists", 409)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
        group.add_users([params[:user_id]], params[:access_level])
 | 
					        group.add_users([params[:user_id]], params[:access_level])
 | 
				
			||||||
        member = group.users_groups.find_by(user_id: params[:user_id])
 | 
					        member = group.group_members.find_by(user_id: params[:user_id])
 | 
				
			||||||
        present member.user, with: Entities::GroupMember, group: group
 | 
					        present member.user, with: Entities::GroupMember, group: group
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,7 +141,7 @@ module API
 | 
				
			||||||
      #   DELETE /groups/:id/members/:user_id
 | 
					      #   DELETE /groups/:id/members/:user_id
 | 
				
			||||||
      delete ":id/members/:user_id" do
 | 
					      delete ":id/members/:user_id" do
 | 
				
			||||||
        group = find_group(params[:id])
 | 
					        group = find_group(params[:id])
 | 
				
			||||||
        member =  group.users_groups.find_by(user_id: params[:user_id])
 | 
					        member =  group.group_members.find_by(user_id: params[:user_id])
 | 
				
			||||||
        if member.nil?
 | 
					        if member.nil?
 | 
				
			||||||
          render_api_error!("404 Not Found - user_id:#{params[:user_id]} not a member of group #{group.name}",404)
 | 
					          render_api_error!("404 Not Found - user_id:#{params[:user_id]} not a member of group #{group.name}",404)
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,8 @@ module API
 | 
				
			||||||
    resource :projects do
 | 
					    resource :projects do
 | 
				
			||||||
      helpers do
 | 
					      helpers do
 | 
				
			||||||
        def handle_project_member_errors(errors)
 | 
					        def handle_project_member_errors(errors)
 | 
				
			||||||
          if errors[:project_access].any?
 | 
					          if errors[:access_level].any?
 | 
				
			||||||
            error!(errors[:project_access], 422)
 | 
					            error!(errors[:access_level], 422)
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
          not_found!
 | 
					          not_found!
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
| 
						 | 
					@ -56,9 +56,9 @@ module API
 | 
				
			||||||
        # either the user is already a team member or a new one
 | 
					        # either the user is already a team member or a new one
 | 
				
			||||||
        team_member = user_project.team_member_by_id(params[:user_id])
 | 
					        team_member = user_project.team_member_by_id(params[:user_id])
 | 
				
			||||||
        if team_member.nil?
 | 
					        if team_member.nil?
 | 
				
			||||||
          team_member = user_project.users_projects.new(
 | 
					          team_member = user_project.project_members.new(
 | 
				
			||||||
            user_id: params[:user_id],
 | 
					            user_id: params[:user_id],
 | 
				
			||||||
            project_access: params[:access_level]
 | 
					            access_level: params[:access_level]
 | 
				
			||||||
          )
 | 
					          )
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,10 +82,10 @@ module API
 | 
				
			||||||
        authorize! :admin_project, user_project
 | 
					        authorize! :admin_project, user_project
 | 
				
			||||||
        required_attributes! [:access_level]
 | 
					        required_attributes! [:access_level]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        team_member = user_project.users_projects.find_by(user_id: params[:user_id])
 | 
					        team_member = user_project.project_members.find_by(user_id: params[:user_id])
 | 
				
			||||||
        not_found!("User can not be found") if team_member.nil?
 | 
					        not_found!("User can not be found") if team_member.nil?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if team_member.update_attributes(project_access: params[:access_level])
 | 
					        if team_member.update_attributes(access_level: params[:access_level])
 | 
				
			||||||
          @member = team_member.user
 | 
					          @member = team_member.user
 | 
				
			||||||
          present @member, with: Entities::ProjectMember, project: user_project
 | 
					          present @member, with: Entities::ProjectMember, project: user_project
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					@ -102,7 +102,7 @@ module API
 | 
				
			||||||
      #   DELETE /projects/:id/members/:user_id
 | 
					      #   DELETE /projects/:id/members/:user_id
 | 
				
			||||||
      delete ":id/members/:user_id" do
 | 
					      delete ":id/members/:user_id" do
 | 
				
			||||||
        authorize! :admin_project, user_project
 | 
					        authorize! :admin_project, user_project
 | 
				
			||||||
        team_member = user_project.users_projects.find_by(user_id: params[:user_id])
 | 
					        team_member = user_project.project_members.find_by(user_id: params[:user_id])
 | 
				
			||||||
        unless team_member.nil?
 | 
					        unless team_member.nil?
 | 
				
			||||||
          team_member.destroy
 | 
					          team_member.destroy
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,10 @@ module Gitlab
 | 
				
			||||||
        options.values
 | 
					        options.values
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def all_values
 | 
				
			||||||
 | 
					        options_with_owner.values
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      def options
 | 
					      def options
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          "Guest"     => GUEST,
 | 
					          "Guest"     => GUEST,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,10 +7,10 @@ namespace :gitlab do
 | 
				
			||||||
      projects_ids = Project.pluck(:id)
 | 
					      projects_ids = Project.pluck(:id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      puts "Importing #{user_ids.size} users into #{projects_ids.size} projects"
 | 
					      puts "Importing #{user_ids.size} users into #{projects_ids.size} projects"
 | 
				
			||||||
      UsersProject.add_users_into_projects(projects_ids, user_ids, UsersProject::DEVELOPER)
 | 
					      ProjectMember.add_users_into_projects(projects_ids, user_ids, ProjectMember::DEVELOPER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      puts "Importing #{admin_ids.size} admins into #{projects_ids.size} projects"
 | 
					      puts "Importing #{admin_ids.size} admins into #{projects_ids.size} projects"
 | 
				
			||||||
      UsersProject.add_users_into_projects(projects_ids, admin_ids, UsersProject::MASTER)
 | 
					      ProjectMember.add_users_into_projects(projects_ids, admin_ids, ProjectMember::MASTER)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    desc "GITLAB | Add a specific user to all projects (as a developer)"
 | 
					    desc "GITLAB | Add a specific user to all projects (as a developer)"
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ namespace :gitlab do
 | 
				
			||||||
      user = User.find_by(email: args.email)
 | 
					      user = User.find_by(email: args.email)
 | 
				
			||||||
      project_ids = Project.pluck(:id)
 | 
					      project_ids = Project.pluck(:id)
 | 
				
			||||||
      puts "Importing #{user.email} users into #{project_ids.size} projects"
 | 
					      puts "Importing #{user.email} users into #{project_ids.size} projects"
 | 
				
			||||||
      UsersProject.add_users_into_projects(project_ids, Array.wrap(user.id), UsersProject::DEVELOPER)
 | 
					      ProjectMember.add_users_into_projects(project_ids, Array.wrap(user.id), ProjectMember::DEVELOPER)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    desc "GITLAB | Add all users to all groups (admin users are added as owners)"
 | 
					    desc "GITLAB | Add all users to all groups (admin users are added as owners)"
 | 
				
			||||||
| 
						 | 
					@ -30,8 +30,8 @@ namespace :gitlab do
 | 
				
			||||||
      puts "Importing #{user_ids.size} users into #{groups.size} groups"
 | 
					      puts "Importing #{user_ids.size} users into #{groups.size} groups"
 | 
				
			||||||
      puts "Importing #{admin_ids.size} admins into #{groups.size} groups"
 | 
					      puts "Importing #{admin_ids.size} admins into #{groups.size} groups"
 | 
				
			||||||
      groups.each do |group|
 | 
					      groups.each do |group|
 | 
				
			||||||
        group.add_users(user_ids, UsersGroup::DEVELOPER)
 | 
					        group.add_users(user_ids, GroupMember::DEVELOPER)
 | 
				
			||||||
        group.add_users(admin_ids, UsersGroup::OWNER)
 | 
					        group.add_users(admin_ids, GroupMember::OWNER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ namespace :gitlab do
 | 
				
			||||||
      groups = Group.all
 | 
					      groups = Group.all
 | 
				
			||||||
      puts "Importing #{user.email} users into #{groups.size} groups"
 | 
					      puts "Importing #{user.email} users into #{groups.size} groups"
 | 
				
			||||||
      groups.each do |group|
 | 
					      groups.each do |group|
 | 
				
			||||||
        group.add_users(Array.wrap(user.id), UsersGroup::DEVELOPER)
 | 
					        group.add_users(Array.wrap(user.id), GroupMember::DEVELOPER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ namespace :gitlab do
 | 
				
			||||||
      check_database_config_exists
 | 
					      check_database_config_exists
 | 
				
			||||||
      check_database_is_not_sqlite
 | 
					      check_database_is_not_sqlite
 | 
				
			||||||
      check_migrations_are_up
 | 
					      check_migrations_are_up
 | 
				
			||||||
      check_orphaned_users_groups
 | 
					      check_orphaned_group_members
 | 
				
			||||||
      check_gitlab_config_exists
 | 
					      check_gitlab_config_exists
 | 
				
			||||||
      check_gitlab_config_not_outdated
 | 
					      check_gitlab_config_not_outdated
 | 
				
			||||||
      check_log_writable
 | 
					      check_log_writable
 | 
				
			||||||
| 
						 | 
					@ -194,13 +194,13 @@ namespace :gitlab do
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def check_orphaned_users_groups
 | 
					    def check_orphaned_group_members
 | 
				
			||||||
      print "Database contains orphaned UsersGroups? ... "
 | 
					      print "Database contains orphaned GroupMembers? ... "
 | 
				
			||||||
      if UsersGroup.where("user_id not in (select id from users)").count > 0
 | 
					      if GroupMember.where("user_id not in (select id from users)").count > 0
 | 
				
			||||||
        puts "yes".red
 | 
					        puts "yes".red
 | 
				
			||||||
        try_fixing_it(
 | 
					        try_fixing_it(
 | 
				
			||||||
          "You can delete the orphaned records using something along the lines of:",
 | 
					          "You can delete the orphaned records using something along the lines of:",
 | 
				
			||||||
          sudo_gitlab("bundle exec rails runner -e production 'UsersGroup.where(\"user_id NOT IN (SELECT id FROM users)\").delete_all'")
 | 
					          sudo_gitlab("bundle exec rails runner -e production 'GroupMember.where(\"user_id NOT IN (SELECT id FROM users)\").delete_all'")
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        puts "no".green
 | 
					        puts "no".green
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,10 +39,10 @@ FactoryGirl.define do
 | 
				
			||||||
    owner
 | 
					    owner
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory :users_project do
 | 
					  factory :project_member do
 | 
				
			||||||
    user
 | 
					    user
 | 
				
			||||||
    project
 | 
					    project
 | 
				
			||||||
    project_access { UsersProject::MASTER }
 | 
					    access_level { ProjectMember::MASTER }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory :issue do
 | 
					  factory :issue do
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
# == Schema Information
 | 
					# == Schema Information
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Table name: users_groups
 | 
					# Table name: group_members
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  id                 :integer          not null, primary key
 | 
					#  id                 :integer          not null, primary key
 | 
				
			||||||
#  group_access       :integer          not null
 | 
					#  group_access       :integer          not null
 | 
				
			||||||
| 
						 | 
					@ -12,8 +12,8 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FactoryGirl.define do
 | 
					FactoryGirl.define do
 | 
				
			||||||
  factory :users_group do
 | 
					  factory :group_member do
 | 
				
			||||||
    group_access { UsersGroup::OWNER }
 | 
					    access_level { GroupMember::OWNER }
 | 
				
			||||||
    group
 | 
					    group
 | 
				
			||||||
    user
 | 
					    user
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ describe GitlabMarkdownHelper do
 | 
				
			||||||
  let(:issue)         { create(:issue, project: project) }
 | 
					  let(:issue)         { create(:issue, project: project) }
 | 
				
			||||||
  let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
 | 
					  let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
 | 
				
			||||||
  let(:snippet)       { create(:project_snippet, project: project) }
 | 
					  let(:snippet)       { create(:project_snippet, project: project) }
 | 
				
			||||||
  let(:member)        { project.users_projects.where(user_id: user).first }
 | 
					  let(:member)        { project.project_members.where(user_id: user).first }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before do
 | 
					  before do
 | 
				
			||||||
    # Helper expects a @project instance variable
 | 
					    # Helper expects a @project instance variable
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,10 +402,10 @@ describe Notify do
 | 
				
			||||||
    describe 'project access changed' do
 | 
					    describe 'project access changed' do
 | 
				
			||||||
      let(:project) { create(:project) }
 | 
					      let(:project) { create(:project) }
 | 
				
			||||||
      let(:user) { create(:user) }
 | 
					      let(:user) { create(:user) }
 | 
				
			||||||
      let(:users_project) { create(:users_project,
 | 
					      let(:project_member) { create(:project_member,
 | 
				
			||||||
                                   project: project,
 | 
					                                   project: project,
 | 
				
			||||||
                                   user: user) }
 | 
					                                   user: user) }
 | 
				
			||||||
      subject { Notify.project_access_granted_email(users_project.id) }
 | 
					      subject { Notify.project_access_granted_email(project_member.id) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it_behaves_like 'an email sent from GitLab'
 | 
					      it_behaves_like 'an email sent from GitLab'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -416,7 +416,7 @@ describe Notify do
 | 
				
			||||||
        should have_body_text /#{project.name}/
 | 
					        should have_body_text /#{project.name}/
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      it 'contains new user role' do
 | 
					      it 'contains new user role' do
 | 
				
			||||||
        should have_body_text /#{users_project.human_access}/
 | 
					        should have_body_text /#{project_member.human_access}/
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -506,7 +506,7 @@ describe Notify do
 | 
				
			||||||
  describe 'group access changed' do
 | 
					  describe 'group access changed' do
 | 
				
			||||||
    let(:group) { create(:group) }
 | 
					    let(:group) { create(:group) }
 | 
				
			||||||
    let(:user) { create(:user) }
 | 
					    let(:user) { create(:user) }
 | 
				
			||||||
    let(:membership) { create(:users_group, group: group, user: user) }
 | 
					    let(:membership) { create(:group_member, group: group, user: user) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    subject { Notify.group_access_granted_email(membership.id) }
 | 
					    subject { Notify.group_access_granted_email(membership.id) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,9 @@
 | 
				
			||||||
# == Schema Information
 | 
					# == Schema Information
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Table name: users_groups
 | 
					# Table name: group_members
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  id                 :integer          not null, primary key
 | 
					#  id                 :integer          not null, primary key
 | 
				
			||||||
#  group_access       :integer          not null
 | 
					#  access_level       :integer          not null
 | 
				
			||||||
#  group_id           :integer          not null
 | 
					#  group_id           :integer          not null
 | 
				
			||||||
#  user_id            :integer          not null
 | 
					#  user_id            :integer          not null
 | 
				
			||||||
#  created_at         :datetime
 | 
					#  created_at         :datetime
 | 
				
			||||||
| 
						 | 
					@ -13,34 +13,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require 'spec_helper'
 | 
					require 'spec_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe UsersGroup do
 | 
					describe GroupMember do
 | 
				
			||||||
  describe "Associations" do
 | 
					 | 
				
			||||||
    it { should belong_to(:group) }
 | 
					 | 
				
			||||||
    it { should belong_to(:user) }
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "Mass assignment" do
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "Validation" do
 | 
					 | 
				
			||||||
    let!(:users_group) { create(:users_group) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it { should validate_presence_of(:user_id) }
 | 
					 | 
				
			||||||
    it { should validate_uniqueness_of(:user_id).scoped_to(:group_id).with_message(/already exists/) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it { should validate_presence_of(:group_id) }
 | 
					 | 
				
			||||||
    it { should ensure_inclusion_of(:group_access).in_array(UsersGroup.group_access_roles.values) }
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "Delegate methods" do
 | 
					 | 
				
			||||||
    it { should respond_to(:user_name) }
 | 
					 | 
				
			||||||
    it { should respond_to(:user_email) }
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  context 'notification' do
 | 
					  context 'notification' do
 | 
				
			||||||
    describe "#after_create" do
 | 
					    describe "#after_create" do
 | 
				
			||||||
      it "should send email to user" do
 | 
					      it "should send email to user" do
 | 
				
			||||||
        membership = build(:users_group)
 | 
					        membership = build(:group_member)
 | 
				
			||||||
        membership.stub(notification_service: double('NotificationService').as_null_object)
 | 
					        membership.stub(notification_service: double('NotificationService').as_null_object)
 | 
				
			||||||
        membership.should_receive(:notification_service)
 | 
					        membership.should_receive(:notification_service)
 | 
				
			||||||
        membership.save
 | 
					        membership.save
 | 
				
			||||||
| 
						 | 
					@ -49,18 +26,18 @@ describe UsersGroup do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe "#after_update" do
 | 
					    describe "#after_update" do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @membership = create :users_group
 | 
					        @membership = create :group_member
 | 
				
			||||||
        @membership.stub(notification_service: double('NotificationService').as_null_object)
 | 
					        @membership.stub(notification_service: double('NotificationService').as_null_object)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should send email to user" do
 | 
					      it "should send email to user" do
 | 
				
			||||||
        @membership.should_receive(:notification_service)
 | 
					        @membership.should_receive(:notification_service)
 | 
				
			||||||
        @membership.update_attribute(:group_access, UsersGroup::MASTER)
 | 
					        @membership.update_attribute(:access_level, GroupMember::MASTER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "does not send an email when the access level has not changed" do
 | 
					      it "does not send an email when the access level has not changed" do
 | 
				
			||||||
        @membership.should_not_receive(:notification_service)
 | 
					        @membership.should_not_receive(:notification_service)
 | 
				
			||||||
        @membership.update_attribute(:group_access, UsersGroup::OWNER)
 | 
					        @membership.update_attribute(:access_level, GroupMember::OWNER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ describe Group do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "Associations" do
 | 
					  describe "Associations" do
 | 
				
			||||||
    it { should have_many :projects }
 | 
					    it { should have_many :projects }
 | 
				
			||||||
    it { should have_many :users_groups }
 | 
					    it { should have_many :group_members }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it { should validate_presence_of :name }
 | 
					  it { should validate_presence_of :name }
 | 
				
			||||||
| 
						 | 
					@ -39,26 +39,26 @@ describe Group do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe :add_users do
 | 
					  describe :add_users do
 | 
				
			||||||
    let(:user) { create(:user) }
 | 
					    let(:user) { create(:user) }
 | 
				
			||||||
    before { group.add_user(user, UsersGroup::MASTER) }
 | 
					    before { group.add_user(user, GroupMember::MASTER) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it { group.users_groups.masters.map(&:user).should include(user) }
 | 
					    it { group.group_members.masters.map(&:user).should include(user) }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe :add_users do
 | 
					  describe :add_users do
 | 
				
			||||||
    let(:user) { create(:user) }
 | 
					    let(:user) { create(:user) }
 | 
				
			||||||
    before { group.add_users([user.id], UsersGroup::GUEST) }
 | 
					    before { group.add_users([user.id], GroupMember::GUEST) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should update the group permission" do
 | 
					    it "should update the group permission" do
 | 
				
			||||||
      group.users_groups.guests.map(&:user).should include(user)
 | 
					      group.group_members.guests.map(&:user).should include(user)
 | 
				
			||||||
      group.add_users([user.id], UsersGroup::DEVELOPER)
 | 
					      group.add_users([user.id], GroupMember::DEVELOPER)
 | 
				
			||||||
      group.users_groups.developers.map(&:user).should include(user)
 | 
					      group.group_members.developers.map(&:user).should include(user)
 | 
				
			||||||
      group.users_groups.guests.map(&:user).should_not include(user)
 | 
					      group.group_members.guests.map(&:user).should_not include(user)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe :avatar_type do
 | 
					  describe :avatar_type do
 | 
				
			||||||
    let(:user) { create(:user) }
 | 
					    let(:user) { create(:user) }
 | 
				
			||||||
    before { group.add_user(user, UsersGroup::MASTER) }
 | 
					    before { group.add_user(user, GroupMember::MASTER) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should be true if avatar is image" do
 | 
					    it "should be true if avatar is image" do
 | 
				
			||||||
      group.update_attribute(:avatar, 'uploads/avatar.png')
 | 
					      group.update_attribute(:avatar, 'uploads/avatar.png')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,4 +12,9 @@ describe Member do
 | 
				
			||||||
    it { should validate_presence_of(:source) }
 | 
					    it { should validate_presence_of(:source) }
 | 
				
			||||||
    it { should ensure_inclusion_of(:access_level).in_array(Gitlab::Access.values) }
 | 
					    it { should ensure_inclusion_of(:access_level).in_array(Gitlab::Access.values) }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe "Delegate methods" do
 | 
				
			||||||
 | 
					    it { should respond_to(:user_name) }
 | 
				
			||||||
 | 
					    it { should respond_to(:user_email) }
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -321,8 +321,8 @@ describe Note do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe :read do
 | 
					    describe :read do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(user: @u2, project_access: UsersProject::GUEST)
 | 
					        @p1.project_members.create(user: @u2, access_level: ProjectMember::GUEST)
 | 
				
			||||||
        @p2.users_projects.create(user: @u3, project_access: UsersProject::GUEST)
 | 
					        @p2.project_members.create(user: @u3, access_level: ProjectMember::GUEST)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it { @abilities.allowed?(@u1, :read_note, @p1).should be_false }
 | 
					      it { @abilities.allowed?(@u1, :read_note, @p1).should be_false }
 | 
				
			||||||
| 
						 | 
					@ -332,8 +332,8 @@ describe Note do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe :write do
 | 
					    describe :write do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(user: @u2, project_access: UsersProject::DEVELOPER)
 | 
					        @p1.project_members.create(user: @u2, access_level: ProjectMember::DEVELOPER)
 | 
				
			||||||
        @p2.users_projects.create(user: @u3, project_access: UsersProject::DEVELOPER)
 | 
					        @p2.project_members.create(user: @u3, access_level: ProjectMember::DEVELOPER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it { @abilities.allowed?(@u1, :write_note, @p1).should be_false }
 | 
					      it { @abilities.allowed?(@u1, :write_note, @p1).should be_false }
 | 
				
			||||||
| 
						 | 
					@ -343,9 +343,9 @@ describe Note do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe :admin do
 | 
					    describe :admin do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(user: @u1, project_access: UsersProject::REPORTER)
 | 
					        @p1.project_members.create(user: @u1, access_level: ProjectMember::REPORTER)
 | 
				
			||||||
        @p1.users_projects.create(user: @u2, project_access: UsersProject::MASTER)
 | 
					        @p1.project_members.create(user: @u2, access_level: ProjectMember::MASTER)
 | 
				
			||||||
        @p2.users_projects.create(user: @u3, project_access: UsersProject::MASTER)
 | 
					        @p2.project_members.create(user: @u3, access_level: ProjectMember::MASTER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it { @abilities.allowed?(@u1, :admin_note, @p1).should be_false }
 | 
					      it { @abilities.allowed?(@u1, :admin_note, @p1).should be_false }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
# == Schema Information
 | 
					# == Schema Information
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Table name: users_projects
 | 
					# Table name: project_members
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#  id                 :integer          not null, primary key
 | 
					#  id                 :integer          not null, primary key
 | 
				
			||||||
#  user_id            :integer          not null
 | 
					#  user_id            :integer          not null
 | 
				
			||||||
| 
						 | 
					@ -13,30 +13,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require 'spec_helper'
 | 
					require 'spec_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe UsersProject do
 | 
					describe ProjectMember do
 | 
				
			||||||
  describe "Associations" do
 | 
					 | 
				
			||||||
    it { should belong_to(:project) }
 | 
					 | 
				
			||||||
    it { should belong_to(:user) }
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "Mass assignment" do
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "Validation" do
 | 
					 | 
				
			||||||
    let!(:users_project) { create(:users_project) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it { should validate_presence_of(:user) }
 | 
					 | 
				
			||||||
    it { should validate_uniqueness_of(:user_id).scoped_to(:project_id).with_message(/already exists/) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it { should validate_presence_of(:project) }
 | 
					 | 
				
			||||||
    it { should ensure_inclusion_of(:project_access).in_array(UsersProject.access_roles.values) }
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "Delegate methods" do
 | 
					 | 
				
			||||||
    it { should respond_to(:user_name) }
 | 
					 | 
				
			||||||
    it { should respond_to(:user_email) }
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe :import_team do
 | 
					  describe :import_team do
 | 
				
			||||||
    before do
 | 
					    before do
 | 
				
			||||||
      @abilities = Six.new
 | 
					      @abilities = Six.new
 | 
				
			||||||
| 
						 | 
					@ -78,10 +55,10 @@ describe UsersProject do
 | 
				
			||||||
      @user_1 = create :user
 | 
					      @user_1 = create :user
 | 
				
			||||||
      @user_2 = create :user
 | 
					      @user_2 = create :user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      UsersProject.add_users_into_projects(
 | 
					      ProjectMember.add_users_into_projects(
 | 
				
			||||||
        [@project_1.id, @project_2.id],
 | 
					        [@project_1.id, @project_2.id],
 | 
				
			||||||
        [@user_1.id, @user_2.id],
 | 
					        [@user_1.id, @user_2.id],
 | 
				
			||||||
        UsersProject::MASTER
 | 
					        ProjectMember::MASTER
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,7 +81,7 @@ describe UsersProject do
 | 
				
			||||||
      @project_1.team << [ @user_1, :developer]
 | 
					      @project_1.team << [ @user_1, :developer]
 | 
				
			||||||
      @project_2.team << [ @user_2, :reporter]
 | 
					      @project_2.team << [ @user_2, :reporter]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      UsersProject.truncate_teams([@project_1.id, @project_2.id])
 | 
					      ProjectMember.truncate_teams([@project_1.id, @project_2.id])
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it { @project_1.users.should be_empty }
 | 
					    it { @project_1.users.should be_empty }
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ describe Project do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe "Guest Rules" do
 | 
					    describe "Guest Rules" do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::GUEST)
 | 
					        @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::GUEST)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should allow for project user any guest actions" do
 | 
					      it "should allow for project user any guest actions" do
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ describe Project do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe "Report Rules" do
 | 
					    describe "Report Rules" do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::REPORTER)
 | 
					        @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::REPORTER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should allow for project user any report actions" do
 | 
					      it "should allow for project user any report actions" do
 | 
				
			||||||
| 
						 | 
					@ -54,8 +54,8 @@ describe Project do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe "Developer Rules" do
 | 
					    describe "Developer Rules" do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::REPORTER)
 | 
					        @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::REPORTER)
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u3, project_access: UsersProject::DEVELOPER)
 | 
					        @p1.project_members.create(project: @p1, user: @u3, access_level: ProjectMember::DEVELOPER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should deny for developer master-specific actions" do
 | 
					      it "should deny for developer master-specific actions" do
 | 
				
			||||||
| 
						 | 
					@ -73,8 +73,8 @@ describe Project do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe "Master Rules" do
 | 
					    describe "Master Rules" do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::DEVELOPER)
 | 
					        @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::DEVELOPER)
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u3, project_access: UsersProject::MASTER)
 | 
					        @p1.project_members.create(project: @p1, user: @u3, access_level: ProjectMember::MASTER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should deny for developer master-specific actions" do
 | 
					      it "should deny for developer master-specific actions" do
 | 
				
			||||||
| 
						 | 
					@ -92,8 +92,8 @@ describe Project do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe "Admin Rules" do
 | 
					    describe "Admin Rules" do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::DEVELOPER)
 | 
					        @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::DEVELOPER)
 | 
				
			||||||
        @p1.users_projects.create(project: @p1, user: @u3, project_access: UsersProject::MASTER)
 | 
					        @p1.project_members.create(project: @p1, user: @u3, access_level: ProjectMember::MASTER)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should deny for masters admin-specific actions" do
 | 
					      it "should deny for masters admin-specific actions" do
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ describe Project do
 | 
				
			||||||
    it { should have_many(:merge_requests).dependent(:destroy) }
 | 
					    it { should have_many(:merge_requests).dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:issues).dependent(:destroy) }
 | 
					    it { should have_many(:issues).dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:milestones).dependent(:destroy) }
 | 
					    it { should have_many(:milestones).dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:users_projects).dependent(:destroy) }
 | 
					    it { should have_many(:project_members).dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:notes).dependent(:destroy) }
 | 
					    it { should have_many(:notes).dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) }
 | 
					    it { should have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:deploy_keys_projects).dependent(:destroy) }
 | 
					    it { should have_many(:deploy_keys_projects).dependent(:destroy) }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ describe SystemHook do
 | 
				
			||||||
      user = create(:user)
 | 
					      user = create(:user)
 | 
				
			||||||
      project = create(:project)
 | 
					      project = create(:project)
 | 
				
			||||||
      project.team << [user, :master]
 | 
					      project.team << [user, :master]
 | 
				
			||||||
      project.users_projects.destroy_all
 | 
					      project.project_members.destroy_all
 | 
				
			||||||
      WebMock.should have_requested(:post, @system_hook.url).with(body: /user_remove_from_team/).once
 | 
					      WebMock.should have_requested(:post, @system_hook.url).with(body: /user_remove_from_team/).once
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,7 @@ describe User do
 | 
				
			||||||
  describe "Associations" do
 | 
					  describe "Associations" do
 | 
				
			||||||
    it { should have_one(:namespace) }
 | 
					    it { should have_one(:namespace) }
 | 
				
			||||||
    it { should have_many(:snippets).class_name('Snippet').dependent(:destroy) }
 | 
					    it { should have_many(:snippets).class_name('Snippet').dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:users_projects).dependent(:destroy) }
 | 
					    it { should have_many(:project_members).dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:groups) }
 | 
					    it { should have_many(:groups) }
 | 
				
			||||||
    it { should have_many(:keys).dependent(:destroy) }
 | 
					    it { should have_many(:keys).dependent(:destroy) }
 | 
				
			||||||
    it { should have_many(:events).class_name('Event').dependent(:destroy) }
 | 
					    it { should have_many(:events).class_name('Event').dependent(:destroy) }
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ describe User do
 | 
				
			||||||
      @group = create :group
 | 
					      @group = create :group
 | 
				
			||||||
      @group.add_owner(@user)
 | 
					      @group.add_owner(@user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @group.add_user(@user2, UsersGroup::OWNER)
 | 
					      @group.add_user(@user2, GroupMember::OWNER)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it { @user2.several_namespaces?.should be_true }
 | 
					    it { @user2.several_namespaces?.should be_true }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,8 +7,8 @@ describe API::API, api: true  do
 | 
				
			||||||
  let(:user) { create(:user) }
 | 
					  let(:user) { create(:user) }
 | 
				
			||||||
  let(:user2) { create(:user) }
 | 
					  let(:user2) { create(:user) }
 | 
				
			||||||
  let!(:project) { create(:project, creator_id: user.id) }
 | 
					  let!(:project) { create(:project, creator_id: user.id) }
 | 
				
			||||||
  let!(:master) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
 | 
					  let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
 | 
				
			||||||
  let!(:guest) { create(:users_project, user: user2, project: project, project_access: UsersProject::GUEST) }
 | 
					  let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) }
 | 
				
			||||||
  let!(:branch_name) { 'feature' }
 | 
					  let!(:branch_name) { 'feature' }
 | 
				
			||||||
  let!(:branch_sha) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' }
 | 
					  let!(:branch_sha) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,8 @@ describe API::API, api: true  do
 | 
				
			||||||
  let(:user) { create(:user) }
 | 
					  let(:user) { create(:user) }
 | 
				
			||||||
  let(:user2) { create(:user) }
 | 
					  let(:user2) { create(:user) }
 | 
				
			||||||
  let!(:project) { create(:project, creator_id: user.id) }
 | 
					  let!(:project) { create(:project, creator_id: user.id) }
 | 
				
			||||||
  let!(:master) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
 | 
					  let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
 | 
				
			||||||
  let!(:guest) { create(:users_project, user: user2, project: project, project_access: UsersProject::GUEST) }
 | 
					  let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before { project.team << [user, :reporter] }
 | 
					  before { project.team << [user, :reporter] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,10 +174,10 @@ describe API::API, api: true  do
 | 
				
			||||||
    let(:guest) { create(:user) }
 | 
					    let(:guest) { create(:user) }
 | 
				
			||||||
    let!(:group_with_members) do
 | 
					    let!(:group_with_members) do
 | 
				
			||||||
      group = create(:group)
 | 
					      group = create(:group)
 | 
				
			||||||
      group.add_users([reporter.id], UsersGroup::REPORTER)
 | 
					      group.add_users([reporter.id], GroupMember::REPORTER)
 | 
				
			||||||
      group.add_users([developer.id], UsersGroup::DEVELOPER)
 | 
					      group.add_users([developer.id], GroupMember::DEVELOPER)
 | 
				
			||||||
      group.add_users([master.id], UsersGroup::MASTER)
 | 
					      group.add_users([master.id], GroupMember::MASTER)
 | 
				
			||||||
      group.add_users([guest.id], UsersGroup::GUEST)
 | 
					      group.add_users([guest.id], GroupMember::GUEST)
 | 
				
			||||||
      group
 | 
					      group
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    let!(:group_no_members) { create(:group) }
 | 
					    let!(:group_no_members) { create(:group) }
 | 
				
			||||||
| 
						 | 
					@ -195,11 +195,11 @@ describe API::API, api: true  do
 | 
				
			||||||
            response.status.should == 200
 | 
					            response.status.should == 200
 | 
				
			||||||
            json_response.should be_an Array
 | 
					            json_response.should be_an Array
 | 
				
			||||||
            json_response.size.should == 5
 | 
					            json_response.size.should == 5
 | 
				
			||||||
            json_response.find { |e| e['id']==owner.id }['access_level'].should == UsersGroup::OWNER
 | 
					            json_response.find { |e| e['id']==owner.id }['access_level'].should == GroupMember::OWNER
 | 
				
			||||||
            json_response.find { |e| e['id']==reporter.id }['access_level'].should == UsersGroup::REPORTER
 | 
					            json_response.find { |e| e['id']==reporter.id }['access_level'].should == GroupMember::REPORTER
 | 
				
			||||||
            json_response.find { |e| e['id']==developer.id }['access_level'].should == UsersGroup::DEVELOPER
 | 
					            json_response.find { |e| e['id']==developer.id }['access_level'].should == GroupMember::DEVELOPER
 | 
				
			||||||
            json_response.find { |e| e['id']==master.id }['access_level'].should == UsersGroup::MASTER
 | 
					            json_response.find { |e| e['id']==master.id }['access_level'].should == GroupMember::MASTER
 | 
				
			||||||
            json_response.find { |e| e['id']==guest.id }['access_level'].should == UsersGroup::GUEST
 | 
					            json_response.find { |e| e['id']==guest.id }['access_level'].should == GroupMember::GUEST
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,29 +213,29 @@ describe API::API, api: true  do
 | 
				
			||||||
    describe "POST /groups/:id/members" do
 | 
					    describe "POST /groups/:id/members" do
 | 
				
			||||||
      context "when not a member of the group" do
 | 
					      context "when not a member of the group" do
 | 
				
			||||||
        it "should not add guest as member of group_no_members when adding being done by person outside the group" do
 | 
					        it "should not add guest as member of group_no_members when adding being done by person outside the group" do
 | 
				
			||||||
          post api("/groups/#{group_no_members.id}/members", reporter), user_id: guest.id, access_level: UsersGroup::MASTER
 | 
					          post api("/groups/#{group_no_members.id}/members", reporter), user_id: guest.id, access_level: GroupMember::MASTER
 | 
				
			||||||
          response.status.should == 403
 | 
					          response.status.should == 403
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      context "when a member of the group" do
 | 
					      context "when a member of the group" do
 | 
				
			||||||
        it "should return ok and add new member" do
 | 
					        it "should return ok and add new member" do
 | 
				
			||||||
          count_before=group_no_members.users_groups.count
 | 
					          count_before=group_no_members.group_members.count
 | 
				
			||||||
          new_user = create(:user)
 | 
					          new_user = create(:user)
 | 
				
			||||||
          post api("/groups/#{group_no_members.id}/members", owner), user_id: new_user.id, access_level: UsersGroup::MASTER
 | 
					          post api("/groups/#{group_no_members.id}/members", owner), user_id: new_user.id, access_level: GroupMember::MASTER
 | 
				
			||||||
          response.status.should == 201
 | 
					          response.status.should == 201
 | 
				
			||||||
          json_response['name'].should == new_user.name
 | 
					          json_response['name'].should == new_user.name
 | 
				
			||||||
          json_response['access_level'].should == UsersGroup::MASTER
 | 
					          json_response['access_level'].should == GroupMember::MASTER
 | 
				
			||||||
          group_no_members.users_groups.count.should == count_before + 1
 | 
					          group_no_members.group_members.count.should == count_before + 1
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it "should return error if member already exists" do
 | 
					        it "should return error if member already exists" do
 | 
				
			||||||
          post api("/groups/#{group_with_members.id}/members", owner), user_id: master.id, access_level: UsersGroup::MASTER
 | 
					          post api("/groups/#{group_with_members.id}/members", owner), user_id: master.id, access_level: GroupMember::MASTER
 | 
				
			||||||
          response.status.should == 409
 | 
					          response.status.should == 409
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it "should return a 400 error when user id is not given" do
 | 
					        it "should return a 400 error when user id is not given" do
 | 
				
			||||||
          post api("/groups/#{group_no_members.id}/members", owner), access_level: UsersGroup::MASTER
 | 
					          post api("/groups/#{group_no_members.id}/members", owner), access_level: GroupMember::MASTER
 | 
				
			||||||
          response.status.should == 400
 | 
					          response.status.should == 400
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,10 +262,10 @@ describe API::API, api: true  do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      context "when a member of the group" do
 | 
					      context "when a member of the group" do
 | 
				
			||||||
        it "should delete guest's membership of group" do
 | 
					        it "should delete guest's membership of group" do
 | 
				
			||||||
          count_before=group_with_members.users_groups.count
 | 
					          count_before=group_with_members.group_members.count
 | 
				
			||||||
          delete api("/groups/#{group_with_members.id}/members/#{guest.id}", owner)
 | 
					          delete api("/groups/#{group_with_members.id}/members/#{guest.id}", owner)
 | 
				
			||||||
          response.status.should == 200
 | 
					          response.status.should == 200
 | 
				
			||||||
          group_with_members.users_groups.count.should == count_before - 1
 | 
					          group_with_members.group_members.count.should == count_before - 1
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it "should return a 404 error when user id is not known" do
 | 
					        it "should return a 404 error when user id is not known" do
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,12 +6,12 @@ describe API::API, api: true  do
 | 
				
			||||||
  let(:user2) { create(:user) }
 | 
					  let(:user2) { create(:user) }
 | 
				
			||||||
  let(:user3) { create(:user) }
 | 
					  let(:user3) { create(:user) }
 | 
				
			||||||
  let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
 | 
					  let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
 | 
				
			||||||
  let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
 | 
					  let(:project_member) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
 | 
				
			||||||
  let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
 | 
					  let(:project_member2) { create(:project_member, user: user3, project: project, access_level: ProjectMember::DEVELOPER) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "GET /projects/:id/members" do
 | 
					  describe "GET /projects/:id/members" do
 | 
				
			||||||
    before { users_project }
 | 
					    before { project_member }
 | 
				
			||||||
    before { users_project2 }
 | 
					    before { project_member2 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return project team members" do
 | 
					    it "should return project team members" do
 | 
				
			||||||
      get api("/projects/#{project.id}/members", user)
 | 
					      get api("/projects/#{project.id}/members", user)
 | 
				
			||||||
| 
						 | 
					@ -36,13 +36,13 @@ describe API::API, api: true  do
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "GET /projects/:id/members/:user_id" do
 | 
					  describe "GET /projects/:id/members/:user_id" do
 | 
				
			||||||
    before { users_project }
 | 
					    before { project_member }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return project team member" do
 | 
					    it "should return project team member" do
 | 
				
			||||||
      get api("/projects/#{project.id}/members/#{user.id}", user)
 | 
					      get api("/projects/#{project.id}/members/#{user.id}", user)
 | 
				
			||||||
      response.status.should == 200
 | 
					      response.status.should == 200
 | 
				
			||||||
      json_response['username'].should == user.username
 | 
					      json_response['username'].should == user.username
 | 
				
			||||||
      json_response['access_level'].should == UsersProject::MASTER
 | 
					      json_response['access_level'].should == ProjectMember::MASTER
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return a 404 error if user id not found" do
 | 
					    it "should return a 404 error if user id not found" do
 | 
				
			||||||
| 
						 | 
					@ -55,29 +55,29 @@ describe API::API, api: true  do
 | 
				
			||||||
    it "should add user to project team" do
 | 
					    it "should add user to project team" do
 | 
				
			||||||
      expect {
 | 
					      expect {
 | 
				
			||||||
        post api("/projects/#{project.id}/members", user), user_id: user2.id,
 | 
					        post api("/projects/#{project.id}/members", user), user_id: user2.id,
 | 
				
			||||||
          access_level: UsersProject::DEVELOPER
 | 
					          access_level: ProjectMember::DEVELOPER
 | 
				
			||||||
      }.to change { UsersProject.count }.by(1)
 | 
					      }.to change { ProjectMember.count }.by(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      response.status.should == 201
 | 
					      response.status.should == 201
 | 
				
			||||||
      json_response['username'].should == user2.username
 | 
					      json_response['username'].should == user2.username
 | 
				
			||||||
      json_response['access_level'].should == UsersProject::DEVELOPER
 | 
					      json_response['access_level'].should == ProjectMember::DEVELOPER
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return a 201 status if user is already project member" do
 | 
					    it "should return a 201 status if user is already project member" do
 | 
				
			||||||
      post api("/projects/#{project.id}/members", user), user_id: user2.id,
 | 
					      post api("/projects/#{project.id}/members", user), user_id: user2.id,
 | 
				
			||||||
        access_level: UsersProject::DEVELOPER
 | 
					        access_level: ProjectMember::DEVELOPER
 | 
				
			||||||
      expect {
 | 
					      expect {
 | 
				
			||||||
        post api("/projects/#{project.id}/members", user), user_id: user2.id,
 | 
					        post api("/projects/#{project.id}/members", user), user_id: user2.id,
 | 
				
			||||||
          access_level: UsersProject::DEVELOPER
 | 
					          access_level: ProjectMember::DEVELOPER
 | 
				
			||||||
      }.not_to change { UsersProject.count }.by(1)
 | 
					      }.not_to change { ProjectMember.count }.by(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      response.status.should == 201
 | 
					      response.status.should == 201
 | 
				
			||||||
      json_response['username'].should == user2.username
 | 
					      json_response['username'].should == user2.username
 | 
				
			||||||
      json_response['access_level'].should == UsersProject::DEVELOPER
 | 
					      json_response['access_level'].should == ProjectMember::DEVELOPER
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return a 400 error when user id is not given" do
 | 
					    it "should return a 400 error when user id is not given" do
 | 
				
			||||||
      post api("/projects/#{project.id}/members", user), access_level: UsersProject::MASTER
 | 
					      post api("/projects/#{project.id}/members", user), access_level: ProjectMember::MASTER
 | 
				
			||||||
      response.status.should == 400
 | 
					      response.status.should == 400
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,17 +93,17 @@ describe API::API, api: true  do
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "PUT /projects/:id/members/:user_id" do
 | 
					  describe "PUT /projects/:id/members/:user_id" do
 | 
				
			||||||
    before { users_project2 }
 | 
					    before { project_member2 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should update project team member" do
 | 
					    it "should update project team member" do
 | 
				
			||||||
      put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: UsersProject::MASTER
 | 
					      put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: ProjectMember::MASTER
 | 
				
			||||||
      response.status.should == 200
 | 
					      response.status.should == 200
 | 
				
			||||||
      json_response['username'].should == user3.username
 | 
					      json_response['username'].should == user3.username
 | 
				
			||||||
      json_response['access_level'].should == UsersProject::MASTER
 | 
					      json_response['access_level'].should == ProjectMember::MASTER
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return a 404 error if user_id is not found" do
 | 
					    it "should return a 404 error if user_id is not found" do
 | 
				
			||||||
      put api("/projects/#{project.id}/members/1234", user), access_level: UsersProject::MASTER
 | 
					      put api("/projects/#{project.id}/members/1234", user), access_level: ProjectMember::MASTER
 | 
				
			||||||
      response.status.should == 404
 | 
					      response.status.should == 404
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,20 +119,20 @@ describe API::API, api: true  do
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "DELETE /projects/:id/members/:user_id" do
 | 
					  describe "DELETE /projects/:id/members/:user_id" do
 | 
				
			||||||
    before { users_project }
 | 
					    before { project_member }
 | 
				
			||||||
    before { users_project2 }
 | 
					    before { project_member2 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should remove user from project team" do
 | 
					    it "should remove user from project team" do
 | 
				
			||||||
      expect {
 | 
					      expect {
 | 
				
			||||||
        delete api("/projects/#{project.id}/members/#{user3.id}", user)
 | 
					        delete api("/projects/#{project.id}/members/#{user3.id}", user)
 | 
				
			||||||
      }.to change { UsersProject.count }.by(-1)
 | 
					      }.to change { ProjectMember.count }.by(-1)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return 200 if team member is not part of a project" do
 | 
					    it "should return 200 if team member is not part of a project" do
 | 
				
			||||||
      delete api("/projects/#{project.id}/members/#{user3.id}", user)
 | 
					      delete api("/projects/#{project.id}/members/#{user3.id}", user)
 | 
				
			||||||
      expect {
 | 
					      expect {
 | 
				
			||||||
        delete api("/projects/#{project.id}/members/#{user3.id}", user)
 | 
					        delete api("/projects/#{project.id}/members/#{user3.id}", user)
 | 
				
			||||||
      }.to_not change { UsersProject.count }.by(1)
 | 
					      }.to_not change { ProjectMember.count }.by(1)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return 200 if team member already removed" do
 | 
					    it "should return 200 if team member already removed" do
 | 
				
			||||||
| 
						 | 
					@ -144,7 +144,7 @@ describe API::API, api: true  do
 | 
				
			||||||
    it "should return 200 OK when the user was not member" do
 | 
					    it "should return 200 OK when the user was not member" do
 | 
				
			||||||
      expect {
 | 
					      expect {
 | 
				
			||||||
        delete api("/projects/#{project.id}/members/1000000", user)
 | 
					        delete api("/projects/#{project.id}/members/1000000", user)
 | 
				
			||||||
      }.to change { UsersProject.count }.by(0)
 | 
					      }.to change { ProjectMember.count }.by(0)
 | 
				
			||||||
      response.status.should == 200
 | 
					      response.status.should == 200
 | 
				
			||||||
      json_response['message'].should == "Access revoked"
 | 
					      json_response['message'].should == "Access revoked"
 | 
				
			||||||
      json_response['id'].should == 1000000
 | 
					      json_response['id'].should == 1000000
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,8 @@ describe API::API, api: true  do
 | 
				
			||||||
  let(:admin) { create(:admin) }
 | 
					  let(:admin) { create(:admin) }
 | 
				
			||||||
  let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
 | 
					  let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
 | 
				
			||||||
  let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
 | 
					  let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
 | 
				
			||||||
  let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
 | 
					  let(:project_member) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
 | 
				
			||||||
  let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
 | 
					  let(:project_member2) { create(:project_member, user: user3, project: project, access_level: ProjectMember::DEVELOPER) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "GET /projects" do
 | 
					  describe "GET /projects" do
 | 
				
			||||||
    before { project }
 | 
					    before { project }
 | 
				
			||||||
| 
						 | 
					@ -254,7 +254,7 @@ describe API::API, api: true  do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "GET /projects/:id" do
 | 
					  describe "GET /projects/:id" do
 | 
				
			||||||
    before { project }
 | 
					    before { project }
 | 
				
			||||||
    before { users_project }
 | 
					    before { project_member }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return a project by id" do
 | 
					    it "should return a project by id" do
 | 
				
			||||||
      get api("/projects/#{project.id}", user)
 | 
					      get api("/projects/#{project.id}", user)
 | 
				
			||||||
| 
						 | 
					@ -283,7 +283,10 @@ describe API::API, api: true  do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe 'permissions' do
 | 
					    describe 'permissions' do
 | 
				
			||||||
      context 'personal project' do
 | 
					      context 'personal project' do
 | 
				
			||||||
        before { get api("/projects/#{project.id}", user) }
 | 
					        before do
 | 
				
			||||||
 | 
					          project.team << [user, :master]
 | 
				
			||||||
 | 
					          get api("/projects/#{project.id}", user)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it { response.status.should == 200 }
 | 
					        it { response.status.should == 200 }
 | 
				
			||||||
        it { json_response['permissions']["project_access"]["access_level"].should == Gitlab::Access::MASTER }
 | 
					        it { json_response['permissions']["project_access"]["access_level"].should == Gitlab::Access::MASTER }
 | 
				
			||||||
| 
						 | 
					@ -305,7 +308,7 @@ describe API::API, api: true  do
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe "GET /projects/:id/events" do
 | 
					  describe "GET /projects/:id/events" do
 | 
				
			||||||
    before { users_project }
 | 
					    before { project_member }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "should return a project events" do
 | 
					    it "should return a project events" do
 | 
				
			||||||
      get api("/projects/#{project.id}/events", user)
 | 
					      get api("/projects/#{project.id}/events", user)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,8 @@ describe API::API, api: true  do
 | 
				
			||||||
  let(:user) { create(:user) }
 | 
					  let(:user) { create(:user) }
 | 
				
			||||||
  let(:user2) { create(:user) }
 | 
					  let(:user2) { create(:user) }
 | 
				
			||||||
  let!(:project) { create(:project, creator_id: user.id) }
 | 
					  let!(:project) { create(:project, creator_id: user.id) }
 | 
				
			||||||
  let!(:master) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
 | 
					  let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
 | 
				
			||||||
  let!(:guest) { create(:users_project, user: user2, project: project, project_access: UsersProject::GUEST) }
 | 
					  let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before { project.team << [user, :reporter] }
 | 
					  before { project.team << [user, :reporter] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,12 +64,12 @@ describe NotificationService do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        before do
 | 
					        before do
 | 
				
			||||||
          note.project.namespace_id = group.id
 | 
					          note.project.namespace_id = group.id
 | 
				
			||||||
          note.project.group.add_user(@u_watcher, UsersGroup::MASTER)
 | 
					          note.project.group.add_user(@u_watcher, GroupMember::MASTER)
 | 
				
			||||||
          note.project.save
 | 
					          note.project.save
 | 
				
			||||||
          user_project = note.project.users_projects.find_by_user_id(@u_watcher.id)
 | 
					          user_project = note.project.project_members.find_by_user_id(@u_watcher.id)
 | 
				
			||||||
          user_project.notification_level = Notification::N_PARTICIPATING
 | 
					          user_project.notification_level = Notification::N_PARTICIPATING
 | 
				
			||||||
          user_project.save
 | 
					          user_project.save
 | 
				
			||||||
          user_group = note.project.group.users_groups.find_by_user_id(@u_watcher.id)
 | 
					          user_group = note.project.group.group_members.find_by_user_id(@u_watcher.id)
 | 
				
			||||||
          user_group.notification_level = Notification::N_GLOBAL
 | 
					          user_group.notification_level = Notification::N_GLOBAL
 | 
				
			||||||
          user_group.save
 | 
					          user_group.save
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ require 'spec_helper'
 | 
				
			||||||
describe SystemHooksService do
 | 
					describe SystemHooksService do
 | 
				
			||||||
  let (:user)          { create :user }
 | 
					  let (:user)          { create :user }
 | 
				
			||||||
  let (:project)       { create :project }
 | 
					  let (:project)       { create :project }
 | 
				
			||||||
  let (:users_project) { create :users_project }
 | 
					  let (:project_member) { create :project_member }
 | 
				
			||||||
  let (:key)           { create(:key, user: user) }
 | 
					  let (:key)           { create(:key, user: user) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  context 'event data' do
 | 
					  context 'event data' do
 | 
				
			||||||
| 
						 | 
					@ -11,8 +11,8 @@ describe SystemHooksService do
 | 
				
			||||||
    it { event_data(user, :destroy).should include(:event_name, :name, :created_at, :email, :user_id) }
 | 
					    it { event_data(user, :destroy).should include(:event_name, :name, :created_at, :email, :user_id) }
 | 
				
			||||||
    it { event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
 | 
					    it { event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
 | 
				
			||||||
    it { event_data(project, :destroy).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
 | 
					    it { event_data(project, :destroy).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
 | 
				
			||||||
    it { event_data(users_project, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access, :project_visibility) }
 | 
					    it { event_data(project_member, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :access_level, :project_visibility) }
 | 
				
			||||||
    it { event_data(users_project, :destroy).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access, :project_visibility) }
 | 
					    it { event_data(project_member, :destroy).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :access_level, :project_visibility) }
 | 
				
			||||||
    it { event_data(key, :create).should include(:username, :key, :id) }
 | 
					    it { event_data(key, :create).should include(:username, :key, :id) }
 | 
				
			||||||
    it { event_data(key, :destroy).should include(:username, :key, :id) }
 | 
					    it { event_data(key, :destroy).should include(:username, :key, :id) }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -22,8 +22,8 @@ describe SystemHooksService do
 | 
				
			||||||
    it { event_name(user, :destroy).should eq "user_destroy" }
 | 
					    it { event_name(user, :destroy).should eq "user_destroy" }
 | 
				
			||||||
    it { event_name(project, :create).should eq "project_create" }
 | 
					    it { event_name(project, :create).should eq "project_create" }
 | 
				
			||||||
    it { event_name(project, :destroy).should eq "project_destroy" }
 | 
					    it { event_name(project, :destroy).should eq "project_destroy" }
 | 
				
			||||||
    it { event_name(users_project, :create).should eq "user_add_to_team" }
 | 
					    it { event_name(project_member, :create).should eq "user_add_to_team" }
 | 
				
			||||||
    it { event_name(users_project, :destroy).should eq "user_remove_from_team" }
 | 
					    it { event_name(project_member, :destroy).should eq "user_remove_from_team" }
 | 
				
			||||||
    it { event_name(key, :create).should eq 'key_create' }
 | 
					    it { event_name(key, :create).should eq 'key_create' }
 | 
				
			||||||
    it { event_name(key, :destroy).should eq 'key_destroy' }
 | 
					    it { event_name(key, :destroy).should eq 'key_destroy' }
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue