GitLab wurde aktualisiert. Dank regelmäßiger Updates bleibt das THM GitLab sicher und Sie profitieren von den neuesten Funktionen. Vielen Dank für Ihre Geduld.

Commit 00a1f5bc authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Project has now correct owner and creator. Increased test coverage

parent 91995909
...@@ -20,7 +20,7 @@ def index ...@@ -20,7 +20,7 @@ def index
@projects = @projects.page(params[:page]).per(30) @projects = @projects.page(params[:page]).per(30)
@events = Event.in_projects(current_user.project_ids) @events = Event.in_projects(current_user.authorized_projects.pluck(:id))
@events = @event_filter.apply_filter(@events) @events = @event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0) @events = @events.limit(20).offset(params[:offset] || 0)
......
...@@ -70,7 +70,7 @@ def group ...@@ -70,7 +70,7 @@ def group
end end
def projects def projects
@projects ||= group.projects.authorized_for(current_user).sorted_by_activity @projects ||= current_user.authorized_projects.where(namespace_id: group.id).sorted_by_activity
end end
def project_ids def project_ids
......
...@@ -32,7 +32,7 @@ class TransferError < StandardError; end ...@@ -32,7 +32,7 @@ class TransferError < StandardError; end
attr_accessible :name, :path, :description, :default_branch, :issues_enabled, attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin] :wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
attr_accessible :namespace_id, :owner_id, as: :admin attr_accessible :namespace_id, :creator_id, as: :admin
attr_accessor :error_code attr_accessor :error_code
...@@ -40,10 +40,10 @@ class TransferError < StandardError; end ...@@ -40,10 +40,10 @@ class TransferError < StandardError; end
belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'" belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'"
belongs_to :namespace belongs_to :namespace
# TODO: replace owner with creator. belongs_to :creator,
# With namespaces a project owner will be a namespace owner class_name: "User",
# so this field makes sense only for global projects foreign_key: "creator_id"
belongs_to :owner, class_name: "User"
has_many :users, through: :users_projects has_many :users, through: :users_projects
has_many :events, dependent: :destroy has_many :events, dependent: :destroy
has_many :merge_requests, dependent: :destroy has_many :merge_requests, dependent: :destroy
...@@ -62,7 +62,7 @@ class TransferError < StandardError; end ...@@ -62,7 +62,7 @@ class TransferError < StandardError; end
delegate :name, to: :owner, allow_nil: true, prefix: true delegate :name, to: :owner, allow_nil: true, prefix: true
# Validations # Validations
validates :owner, presence: true validates :creator, presence: true
validates :description, length: { within: 0..2000 } validates :description, length: { within: 0..2000 }
validates :name, presence: true, length: { within: 0..255 }, validates :name, presence: true, length: { within: 0..255 },
format: { with: Gitlab::Regex.project_name_regex, format: { with: Gitlab::Regex.project_name_regex,
...@@ -89,8 +89,7 @@ class TransferError < StandardError; end ...@@ -89,8 +89,7 @@ class TransferError < StandardError; end
class << self class << self
def authorized_for user def authorized_for user
projects = includes(:users_projects, :namespace) raise "DERECATED"
projects = projects.where("users_projects.user_id = :user_id or projects.owner_id = :user_id or namespaces.owner_id = :user_id", user_id: user.id)
end end
def active def active
...@@ -104,8 +103,10 @@ def search query ...@@ -104,8 +103,10 @@ def search query
def find_with_namespace(id) def find_with_namespace(id)
if id.include?("/") if id.include?("/")
id = id.split("/") id = id.split("/")
namespace_id = Namespace.find_by_path(id.first).id namespace = Namespace.find_by_path(id.first)
where(namespace_id: namespace_id).find_by_path(id.second) return nil unless namespace
where(namespace_id: namespace.id).find_by_path(id.second)
else else
where(path: id, namespace_id: nil).last where(path: id, namespace_id: nil).last
end end
...@@ -125,7 +126,7 @@ def create_by_user(params, user) ...@@ -125,7 +126,7 @@ def create_by_user(params, user)
# #
project.path = project.name.dup.parameterize project.path = project.name.dup.parameterize
project.owner = user project.creator = user
# Apply namespace if user has access to it # Apply namespace if user has access to it
# else fallback to user namespace # else fallback to user namespace
...@@ -174,8 +175,8 @@ def saved? ...@@ -174,8 +175,8 @@ def saved?
end end
def check_limit def check_limit
unless owner.can_create_project? unless creator.can_create_project?
errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it") errors[:base] << ("Your own projects limit is #{creator.projects_limit}! Please contact administrator to increase it")
end end
rescue rescue
errors[:base] << ("Can't check your ability to create project") errors[:base] << ("Can't check your ability to create project")
...@@ -268,4 +269,12 @@ def send_move_instructions ...@@ -268,4 +269,12 @@ def send_move_instructions
Notify.project_was_moved_email(member.id).deliver Notify.project_was_moved_email(member.id).deliver
end end
end end
def owner
if namespace
namespace_owner
else
creator
end
end
end end
...@@ -51,7 +51,6 @@ class User < ActiveRecord::Base ...@@ -51,7 +51,6 @@ class User < ActiveRecord::Base
has_many :groups, class_name: "Group", foreign_key: :owner_id has_many :groups, class_name: "Group", foreign_key: :owner_id
has_many :keys, dependent: :destroy has_many :keys, dependent: :destroy
has_many :projects, through: :users_projects
has_many :users_projects, dependent: :destroy has_many :users_projects, dependent: :destroy
has_many :issues, foreign_key: :author_id, dependent: :destroy has_many :issues, foreign_key: :author_id, dependent: :destroy
has_many :notes, foreign_key: :author_id, dependent: :destroy has_many :notes, foreign_key: :author_id, dependent: :destroy
...@@ -82,6 +81,9 @@ class User < ActiveRecord::Base ...@@ -82,6 +81,9 @@ class User < ActiveRecord::Base
scope :active, where(blocked: false) scope :active, where(blocked: false)
scope :alphabetically, order('name ASC') scope :alphabetically, order('name ASC')
#
# Class methods
#
class << self class << self
def filter filter_name def filter filter_name
case filter_name case filter_name
...@@ -126,9 +128,63 @@ def search query ...@@ -126,9 +128,63 @@ def search query
end end
end end
#
# Instance methods
#
def generate_password def generate_password
if self.force_random_password if self.force_random_password
self.password = self.password_confirmation = Devise.friendly_token.first(8) self.password = self.password_confirmation = Devise.friendly_token.first(8)
end end
end end
# Namespaces user has access to
def namespaces
namespaces = []
# Add user account namespace
namespaces << self.namespace if self.namespace
# Add groups you can manage
namespaces += if admin
Group.all
else
groups.all
end
namespaces
end
# Groups where user is an owner
def owned_groups
groups
end
# Groups user has access to
def authorized_groups
@authorized_groups ||= begin
groups = Group.where(id: self.authorized_projects.pluck(:namespace_id)).all
groups = groups + self.groups
groups.uniq
end
end
# Projects user has access to
def authorized_projects
project_ids = users_projects.pluck(:project_id)
project_ids = project_ids | owned_projects.pluck(:id)
Project.where(id: project_ids)
end
# Projects in user namespace
def personal_projects
Project.personal(self)
end
# Projects where user is an owner
def owned_projects
Project.where("(projects.namespace_id IN (:namespaces)) OR
(projects.namespace_id IS NULL AND projects.creator_id = :user_id)",
namespaces: namespaces.map(&:id), user_id: self.id)
end
end end
...@@ -25,7 +25,7 @@ def require_ssh_key? ...@@ -25,7 +25,7 @@ def require_ssh_key?
end end
def can_create_project? def can_create_project?
projects_limit > my_own_projects.count projects_limit > personal_projects.count
end end
def can_create_group? def can_create_group?
...@@ -56,10 +56,6 @@ def cared_merge_requests ...@@ -56,10 +56,6 @@ def cared_merge_requests
MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id) MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id)
end end
def project_ids
projects.map(&:id)
end
# Remove user from all projects and # Remove user from all projects and
# set blocked attribute to true # set blocked attribute to true
def block def block
...@@ -86,22 +82,7 @@ def recent_push project_id = nil ...@@ -86,22 +82,7 @@ def recent_push project_id = nil
end end
def projects_sorted_by_activity def projects_sorted_by_activity
projects.sorted_by_activity authorized_projects.sorted_by_activity
end
def namespaces
namespaces = []
# Add user account namespace
namespaces << self.namespace if self.namespace
# Add groups you can manage
namespaces += if admin
Group.all
else
groups.all
end
namespaces
end end
def several_namespaces? def several_namespaces?
...@@ -111,20 +92,4 @@ def several_namespaces? ...@@ -111,20 +92,4 @@ def several_namespaces?
def namespace_id def namespace_id
namespace.try :id namespace.try :id
end end
def authorized_groups
@authorized_groups ||= begin
groups = Group.where(id: self.projects.pluck(:namespace_id)).all
groups = groups + self.groups
groups.uniq
end
end
def authorized_projects
Project.authorized_for(self)
end
def my_own_projects
Project.personal(self)
end
end end
...@@ -50,14 +50,6 @@ def namespace_owner ...@@ -50,14 +50,6 @@ def namespace_owner
namespace.try(:owner) namespace.try(:owner)
end end
def chief
if namespace
namespace_owner
else
owner
end
end
def path_with_namespace def path_with_namespace
if namespace if namespace
namespace.path + '/' + path namespace.path + '/' + path
......
...@@ -49,8 +49,8 @@ ...@@ -49,8 +49,8 @@
%b %b
Owned by: Owned by:
%td %td
- if @project.chief - if @project.owner
= link_to @project.chief.name, admin_user_path(@project.chief) = link_to @project.owner_name, admin_user_path(@project.owner)
- else - else
(deleted) (deleted)
%tr %tr
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
%b %b
Created by: Created by:
%td %td
= @project.owner_name || '(deleted)' = @project.creator.try(:name) || '(deleted)'
%tr %tr
%td %td
%b %b
......
...@@ -17,4 +17,4 @@ ...@@ -17,4 +17,4 @@
&rarr; &rarr;
%span.last_activity %span.last_activity
%strong Projects: %strong Projects:
%span= group.projects.authorized_for(current_user).count %span= current_user.authorized_projects.where(namespace_id: group.id).count
class RenameOwnerToCreatorForProject < ActiveRecord::Migration
def change
rename_column :projects, :owner_id, :creator_id
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20121219095402) do ActiveRecord::Schema.define(:version => 20130102143055) do
create_table "events", :force => true do |t| create_table "events", :force => true do |t|
t.string "target_type" t.string "target_type"
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
t.boolean "private_flag", :default => true, :null => false t.boolean "private_flag", :default => true, :null => false
t.integer "owner_id" t.integer "creator_id"
t.string "default_branch" t.string "default_branch"
t.boolean "issues_enabled", :default => true, :null => false t.boolean "issues_enabled", :default => true, :null => false
t.boolean "wall_enabled", :default => true, :null => false t.boolean "wall_enabled", :default => true, :null => false
...@@ -157,8 +157,8 @@ ...@@ -157,8 +157,8 @@
t.integer "namespace_id" t.integer "namespace_id"
end end
add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
add_index "projects", ["namespace_id"], :name => "index_projects_on_namespace_id" add_index "projects", ["namespace_id"], :name => "index_projects_on_namespace_id"
add_index "projects", ["owner_id"], :name => "index_projects_on_owner_id"
create_table "protected_branches", :force => true do |t| create_table "protected_branches", :force => true do |t|
t.integer "project_id", :null => false t.integer "project_id", :null => false
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
sequence(:url) { Faker::Internet.uri('http') } sequence(:url) { Faker::Internet.uri('http') }
factory :user, aliases: [:author, :assignee, :owner] do factory :user, aliases: [:author, :assignee, :owner, :creator] do
email { Faker::Internet.email } email { Faker::Internet.email }
name name
username { Faker::Internet.user_name } username { Faker::Internet.user_name }
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
factory :project do factory :project do
sequence(:name) { |n| "project#{n}" } sequence(:name) { |n| "project#{n}" }
path { name.downcase.gsub(/\s/, '_') } path { name.downcase.gsub(/\s/, '_') }
owner creator
end end
factory :group do factory :group do
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
@u1 = create(:user) @u1 = create(:user)
@u2 = create(:user) @u2 = create(:user)
@u3 = create(:user) @u3 = create(:user)
@u4 = @p1.chief @u4 = @p1.owner
@abilities = Six.new @abilities = Six.new
@abilities << Ability @abilities << Ability
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
describe "Associations" do describe "Associations" do
it { should belong_to(:group) } it { should belong_to(:group) }
it { should belong_to(:namespace) } it { should belong_to(:namespace) }
it { should belong_to(:owner).class_name('User') } it { should belong_to(:creator).class_name('User') }
it { should have_many(:users) } it { should have_many(:users) }
it { should have_many(:events).dependent(:destroy) } it { should have_many(:events).dependent(:destroy) }
it { should have_many(:merge_requests).dependent(:destroy) } it { should have_many(:merge_requests).dependent(:destroy) }
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
describe "Mass assignment" do describe "Mass assignment" do
it { should_not allow_mass_assignment_of(:namespace_id) } it { should_not allow_mass_assignment_of(:namespace_id) }
it { should_not allow_mass_assignment_of(:owner_id) } it { should_not allow_mass_assignment_of(:creator_id) }
it { should_not allow_mass_assignment_of(:private_flag) } it { should_not allow_mass_assignment_of(:private_flag) }
end end
...@@ -55,20 +55,15 @@ ...@@ -55,20 +55,15 @@
it { should validate_presence_of(:path) } it { should validate_presence_of(:path) }
it { should validate_uniqueness_of(:path) } it { should validate_uniqueness_of(:path) }
it { should ensure_length_of(:path).is_within(0..255) } it { should ensure_length_of(:path).is_within(0..255) }
# TODO: Formats
it { should ensure_length_of(:description).is_within(0..2000) } it { should ensure_length_of(:description).is_within(0..2000) }
it { should validate_presence_of(:creator) }
# TODO: Formats
it { should validate_presence_of(:owner) }
it { should ensure_inclusion_of(:issues_enabled).in_array([true, false]) } it { should ensure_inclusion_of(:issues_enabled).in_array([true, false]) }
it { should ensure_inclusion_of(:wall_enabled).in_array([true, false]) } it { should ensure_inclusion_of(:wall_enabled).in_array([true, false]) }
it { should ensure_inclusion_of(:merge_requests_enabled).in_array([true, false]) } it { should ensure_inclusion_of(:merge_requests_enabled).in_array([true, false]) }
it { should ensure_inclusion_of(:wiki_enabled).in_array([true, false]) } it { should ensure_inclusion_of(:wiki_enabled).in_array([true, false]) }
it "should not allow new projects beyond user limits" do it "should not allow new projects beyond user limits" do
project.stub(:owner).and_return(double(can_create_project?: false, projects_limit: 1)) project.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 1))
project.should_not be_valid project.should_not be_valid
project.errors[:base].first.should match(/Your own projects limit is 1/) project.errors[:base].first.should match(/Your own projects limit is 1/)
end end
...@@ -134,7 +129,7 @@ ...@@ -134,7 +129,7 @@
it { should respond_to(:transfer) } it { should respond_to(:transfer) }
it { should respond_to(:name_with_namespace) } it { should respond_to(:name_with_namespace) }
it { should respond_to(:namespace_owner) } it { should respond_to(:namespace_owner) }
it { should respond_to(:chief) } it { should respond_to(:owner) }
it { should respond_to(:path_with_namespace) } it { should respond_to(:path_with_namespace) }
end end
...@@ -211,4 +206,75 @@ ...@@ -211,4 +206,75 @@
@merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
end end
end end
describe :create_by_user do
before do
@user = create :user
@opts = {
name: "GitLab"
}
end
context 'user namespace' do
before do
@project = Project.create_by_user(@opts, @user)
end
it { @project.should be_valid }
it { @project.owner.should == @user }
it { @project.namespace.should == @user.namespace }
end
context 'user namespace' do
before do
@group = create :group, owner: @user
@opts.merge!(namespace_id: @group.id)
@project = Project.create_by_user(@opts, @user)
end
it { @project.should be_valid }
it { @project.owner.should == @user }
it { @project.namespace.should == @group }
end
end
describe :find_with_namespace do
context 'with namespace' do
before do
@group = create :group, name: 'gitlab'
@project = create(:project, name: 'gitlab-ci', namespace: @group)
end
it { Project.find_with_namespace('gitlab/gitlab-ci').should == @project }
it { Project.find_with_namespace('gitlab-ci').should be_nil }
end
context 'w/o namespace' do
before do
@project = create(:project, name: 'gitlab-ci')
end
it { Project.find_with_namespace('gitlab-ci').should == @project }
it { Project.find_with_namespace('gitlab/gitlab-ci').should be_nil }
end
end
describe :to_param do
context 'with namespace' do
before do
@group = create :group, name: 'gitlab'
@project = create(:project, name: 'gitlab-ci', namespace: @group)
end
it { @project.<