Commit 8cd88235 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch '7-4-pre' into 'master'

7.4 development

Development branch during `master` code freeze for 7.3

See merge request !1096
parents b3c53efc 64855704
...@@ -106,7 +106,7 @@ GEM ...@@ -106,7 +106,7 @@ GEM
devise (~> 3.2) devise (~> 3.2)
diff-lcs (1.2.5) diff-lcs (1.2.5)
diffy (3.0.3) diffy (3.0.3)
docile (1.1.1) docile (1.1.5)
dotenv (0.9.0) dotenv (0.9.0)
dropzonejs-rails (0.4.14) dropzonejs-rails (0.4.14)
rails (> 3.1) rails (> 3.1)
...@@ -471,7 +471,7 @@ GEM ...@@ -471,7 +471,7 @@ GEM
redis (>= 3.0.4) redis (>= 3.0.4)
redis-namespace (>= 1.3.1) redis-namespace (>= 1.3.1)
simple_oauth (0.1.9) simple_oauth (0.1.9)
simplecov (0.8.2) simplecov (0.9.0)
docile (~> 1.1.0) docile (~> 1.1.0)
multi_json multi_json
simplecov-html (~> 0.8.0) simplecov-html (~> 0.8.0)
......
...@@ -46,10 +46,10 @@ class Admin ...@@ -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
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 ...@@ -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 ...@@ -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 ...@@ -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
......
class UsersGroupsController < ApplicationController class Groups::GroupMembersController < ApplicationController
before_filter :group before_filter :group
# Authorize # Authorize
...@@ -7,18 +7,18 @@ class UsersGroupsController < ApplicationController ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
...@@ -187,13 +187,6 @@ module ApplicationHelper ...@@ -187,13 +187,6 @@ module ApplicationHelper
end end
end end
def first_line(str)
lines = str.split("\n")
line = lines.first
line += "..." if lines.size > 1
line
end
def broadcast_message def broadcast_message
BroadcastMessage.current BroadcastMessage.current
end end
......
...@@ -136,7 +136,7 @@ module EventsHelper ...@@ -136,7 +136,7 @@ module EventsHelper
end end
def event_note(text) def event_note(text)
text = first_line(text) text = first_line_in_markdown(text)
text = truncate(text, length: 150) text = truncate(text, length: 150)
sanitize(markdown(text), tags: %w(a img b pre p)) sanitize(markdown(text), tags: %w(a img b pre p))
end end
......
...@@ -51,6 +51,14 @@ module GitlabMarkdownHelper ...@@ -51,6 +51,14 @@ module GitlabMarkdownHelper
@markdown.render(text).html_safe @markdown.render(text).html_safe
end end
def first_line_in_markdown(text)
line = text.split("\n").detect do |i|
i.present? && markdown(i).present?
end
line += '...' unless line.nil?
line
end
def render_wiki_content(wiki_page) def render_wiki_content(wiki_page)
if wiki_page.format == :markdown if wiki_page.format == :markdown
markdown(wiki_page.content) markdown(wiki_page.content)
......
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,
......
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 ...@@ -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
......
# == 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' ...@@ -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 ...@@ -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 ...@@ -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
......
class Member < ActiveRecord::Base
include Notifiable
include Gitlab::Access
belongs_to :user
belongs_to :source, polymorphic: true
validates :user, presence: true
validates :source, presence: true
validates :user_id, uniqueness: { scope: [:source_type, :source_id], message: "already exists in source" }
validates :access_level, inclusion: { in: Gitlab::Access.all_values }, presence: true
scope :guests, -> { where(access_level: GUEST) }
scope :reporters, -> { where(access_level: REPORTER) }
scope :developers, -> { where(access_level: DEVELOPER) }
scope :masters, -> { where(access_level: MASTER) }
scope :owners, -> { where(access_level: OWNER) }
delegate :name, :username, :email, to: :user, prefix: true
end
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
# == Schema Information class ProjectMember < Member
# SOURCE_TYPE = 'Project'
# 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 include Gitlab::ShellAdapter
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 belongs_to :project, class_name: 'Project', foreign_key: 'source_id'
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) } # Make sure project member points only to project as it source
scope :in_projects, ->(projects) { where(project_id: projects.map { |p| p.id }) } default_value_for :source_type, SOURCE_TYPE
scope :with_user, ->(user) { where(user_id: user.id) } 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_create :post_create_hook
after_update :post_update_hook after_update :post_update_hook
after_destroy :post_destroy_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 class << self
# Add users to project teams with passed access option # Add users to project teams with passed access option
...@@ -50,7 +31,7 @@ class UsersProject < ActiveRecord::Base ...@@ -50,7 +31,7 @@ class UsersProject < ActiveRecord::Base
# add_users_into_projects( # add_users_into_projects(
# project_ids, # project_ids,
# user_ids, # user_ids,
# UsersProject::MASTER # ProjectMember::MASTER
# ) # )
# #
# add_users_into_projects( # add_users_into_projects(
...@@ -60,7 +41,7 @@ class UsersProject < ActiveRecord::Base ...@@ -60,7 +41,7 @@ class UsersProject < ActiveRecord::Base
# ) # )
# #
def add_users_into_projects(project_ids, user_ids, access) def add_users_into_projects(project_ids, user_ids, access)
project_access = if roles_hash.has_key?(access) access_level = if roles_hash.has_key?(access)
roles_hash[access] roles_hash[access]
elsif roles_hash.values.include?(access.to_i) elsif roles_hash.values.include?(access.to_i)
access access
...@@ -68,12 +49,12 @@ class UsersProject < ActiveRecord::Base ...@@ -68,12 +49,12 @@ class UsersProject < ActiveRecord::Base
raise "Non valid access" raise "Non valid access"
end end
UsersProject.transaction do ProjectMember.transaction do
project_ids.each do |project_id| project_ids.each do |project_id|
user_ids.each do |user_id| user_ids.each do |user_id|
users_project = UsersProject.new(project_access: project_access, user_id: user_id) member = ProjectMember.new(access_level: access_level, user_id: user_id)
users_project.project_id = project_id member.source_id = project_id
users_project.save member.save
end end
end end
end end
...@@ -84,10 +65,10 @@ class UsersProject < ActiveRecord::Base ...@@ -84,10 +65,10 @@ class UsersProject < ActiveRecord::Base
end end
def truncate_teams(project_ids) def truncate_teams(project_ids)
UsersProject.transaction do ProjectMember.transaction do
users_projects = UsersProject.where(project_id: project_ids) members = ProjectMember.where(source_id: project_ids)
users_projects.each do |users_project| members.each do |member|
users_project.destroy member.destroy
end end
end end
...@@ -110,7 +91,7 @@ class UsersProject < ActiveRecord::Base ...@@ -110,7 +91,7 @@ class UsersProject < ActiveRecord::Base
end end
def access_field def access_field
project_access access_level
end end
def owner? def owner?
...@@ -129,7 +110,7 @@ class UsersProject < ActiveRecord::Base ...@@ -129,7 +110,7 @@ class UsersProject < ActiveRecord::Base
end end
def post_update_hook def post_update_hook
notification_service.update_team_member(self) if self.project_access_changed? notification_service.update_team_member(self) if self.access_level_changed?
end end
def post_destroy_hook def post_destroy_hook
...@@ -149,4 +130,8 @@ class UsersProject < ActiveRecord::Base ...@@ -149,4 +130,8 @@ class UsersProject < ActiveRecord::Base
def system_hook_service def system_hook_service
SystemHooksService.new SystemHooksService.new
end end
def project
source
end
end end
...@@ -79,8 +79,8 @@ class Project < ActiveRecord::Base ...@@ -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 ...@@ -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 ...@@ -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
......
...@@ -32,12 +32,12 @@ class ProjectTeam ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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?
......
# == 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
...@@ -157,12 +157,12 @@ class NotificationService ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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
......
%div{xmlns: "http://www.w3.org/1999/xhtml"} %div{xmlns: "http://www.w3.org/1999/xhtml"}
- if issue.description.present?
= markdown issue.description = markdown issue.description
%div{xmlns: "http://www.w3.org/1999/xhtml"} %div{xmlns: "http://www.w3.org/1999/xhtml"}
- if merge_request.description.present?
= markdown merge_request.description = markdown merge_request.description
= 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 @@ ...@@ -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 @@ ...@@ -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
......
%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
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 @@ ...@@ -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 @@ ...@@ -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
%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 @@ ...@@ -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"
......
- 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 @@ ...@@ -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 @@ ...@@ -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"
&nbsp; &nbsp;
= 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 @@ ...@@ -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"
%article.readme-holder#README %article.readme-holder#README
= link_to '#README' do
%h4.readme-file-title %h4.readme-file-title
%i.icon-file %i.icon-file
= readme.name = readme.name
......
...@@ -12,7 +12,12 @@ module Gitlab ...@@ -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 ...@@ -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
......
Gitlab::Seeder.quiet do Gitlab::Seeder.quiet do
Group.all.each do |group| Group.all.each do |group|
User.all.sample(4).each do |user| User.all.sample(4).each do |user|
if group.add_users([user.id], UsersGroup.group_access_roles.values.sample) if group.add_users([user.id], Gitlab::Access.values.sample)
print '.' print '.'
else else
print 'F' print 'F'
...@@ -11,7 +11,7 @@ Gitlab::Seeder.quiet do ...@@ -11,7 +11,7 @@ Gitlab::Seeder.quiet do
Project.all.each do |project| Project.all.each do |project|
User.all.sample(4).each do |user| User.all.sample(4).each do |user|
if project.team << [user, UsersProject.access_roles.values.sample] if project.team << [user, Gitlab::Access.values.sample]
print '.' print '.'
else else
print 'F' print 'F'
......
class AddMembersTable < ActiveRecord::Migration
def change
create_table :members do |t|
t.integer :access_level, null: false
t.integer :source_id, null: false
t.string :source_type, null: false
t.integer :user_id, null: false
t.integer :notification_level, null: false
t.string :type
t.timestamps
end
add_index :members, :type
add_index :members, :user_id
add_index :members, :access_level
add_index :members, [:source_id, :source_type]
end
end
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
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
...@@ -11,7 +11,7 @@ ...@@ -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: 20140907220153) 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"
...@@ -130,6 +130,22 @@ ActiveRecord::Schema.define(version: 20140907220153) do ...@@ -130,6 +130,22 @@ ActiveRecord::Schema.define(version: 20140907220153) do
add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree
create_table "members", force: true do |t|
t.integer "access_level", null: false
t.integer "source_id", null: false
t.string "source_type", null: false
t.integer "user_id", null: false
t.integer "notification_level", null: false
t.string "type"
t.datetime "created_at"
t.datetime "updated_at"
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"
...@@ -363,30 +379,6 @@ ActiveRecord::Schema.define(version: 20140907220153) do ...@@ -363,30 +379,6 @@ ActiveRecord::Schema.define(version: 20140907220153) 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 ...@@ -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
......
...@@ -82,6 +82,4 @@ class EventFilters < Spinach::FeatureSteps ...@@ -82,6 +82,4 @@ class EventFilters < Spinach::FeatureSteps
When 'I click "merge" event filter' do When 'I click "merge" event filter' do
click_link("merged_event_filter") click_link("merged_event_filter")
end end
end end
...@@ -32,7 +32,7 @@ class Groups < Spinach::FeatureSteps ...@@ -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
......
...@@ -77,8 +77,10 @@ class ProjectBrowseFiles < Spinach::FeatureSteps ...@@ -77,8 +77,10 @@ class ProjectBrowseFiles < Spinach::FeatureSteps
end end
step 'I click on readme file' do step 'I click on readme file' do
within '.tree-table' do
click_link 'README.md' click_link 'README.md'
end end
end
step 'I see Browse file link' do step 'I see Browse file link' do
page.should have_link 'Browse File »' page.should have_link 'Browse File »'
......
...@@ -79,10 +79,18 @@ class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps ...@@ -79,10 +79,18 @@ class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps
end end
And 'I navigate to the doc/api/README' do And 'I navigate to the doc/api/README' do
within '.tree-table' do
click_link "doc" click_link "doc"
end
within '.tree-table' do
click_link "api" click_link "api"
end
within '.tree-table' do
click_link "README.md" click_link "README.md"
end end
end
And 'I see correct file rendered' do And 'I see correct file rendered' do
current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") current_path.should == project_blob_path(@project, "markdown/doc/api/README.md")
......
...@@ -23,8 +23,8 @@ class ProjectTeamManagement < Spinach::FeatureSteps ...@@ -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 ...@@ -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
......
require 'simplecov' unless ENV['CI'] if ENV['SIMPLECOV']
require 'simplecov'
end
if ENV['TRAVIS'] if ENV['COVERALLS']
require 'coveralls' require 'coveralls'
Coveralls.wear! Coveralls.wear_merged!('rails')
end end
ENV['RAILS_ENV'] = 'test' ENV['RAILS_ENV'] = 'test'
require './config/environment' require './config/environment'
require 'rspec' require 'rspec'
require 'rspec/expectations' require 'rspec/expectations'
require 'database_cleaner' require 'database_cleaner'
require 'spinach/capybara' require 'spinach/capybara'
require 'sidekiq/testing/inline' require 'sidekiq/testing/inline'
%w(select2_helper test_env repo_helpers).each do |f| %w(select2_helper test_env repo_helpers).each do |f|
require Rails.root.join('spec', 'support', f) require Rails.root.join('spec', 'support', f)
end end
......
...@@ -53,8 +53,8 @@ module API ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
# == 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 @@ ...@@ -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
......
...@@ -10,5 +10,34 @@ describe "Dashboard Feed", feature: true do ...@@ -10,5 +10,34 @@ describe "Dashboard Feed", feature: true do
page.body.should have_selector("feed title") page.body.should have_selector("feed title")
end end
end end
context 'feed content' do
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project, author: user, description: '') }
let(:note) { create(:note, noteable: issue, author: user, note: 'Bug confirmed', project: project) }
before do
project.team << [user, :master]
issue_event(issue, user)
note_event(note, user)
visit dashboard_path(:atom, private_token: user.private_token)
end
it "should have issue opened event" do
page.body.should have_content("#{user.name} opened issue ##{issue.iid}")
end
it "should have issue comment event" do
page.body.should have_content("#{user.name} commented on issue ##{issue.iid}")
end
end
end
def issue_event(issue, user)
EventCreateService.new.open_issue(issue, user)
end
def note_event(note, user)
EventCreateService.new.leave_note(note, user)
end end
end end
...@@ -12,7 +12,7 @@ describe GitlabMarkdownHelper do ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) }
......
# == 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 @@ ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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')
......
require 'spec_helper'
describe Member do
describe "Associations" do
it { should belong_to(:user) }
end
describe "Validation" do
subject { Member.new(access_level: Member::GUEST) }
it { should validate_presence_of(:user) }
it { should validate_presence_of(:source) }
it { should ensure_inclusion_of(:access_level).in_array(Gitlab::Access.values) }
end
describe "Delegate methods" do
it { should respond_to(:user_name) }
it { should respond_to(:user_email) }
end
end
...@@ -321,8 +321,8 @@ describe Note do ...@@ -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 ...@@ -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 ...@@ -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 }
......
# == 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 @@ ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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' ...@@ -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 ...@@ -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 ...@@ -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
......
# This file is copied to spec/ when you run 'rails generate rspec:install' if ENV['SIMPLECOV']
ENV["RAILS_ENV"] ||= 'test' require 'simplecov'
require File.expand_path("../../config/environment", __FILE__) end
require 'simplecov' unless ENV['CI']
if ENV['TRAVIS'] if ENV['COVERALLS']
require 'coveralls' require 'coveralls'
Coveralls.wear! Coveralls.wear_merged!('rails')
end end
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails' require 'rspec/rails'
require 'capybara/rails' require 'capybara/rails'
require 'capybara/rspec' require 'capybara/rspec'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment