Commit b01f8b63 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

added NamespacedProject role. Extended project info displayed for admin. Fixed project limit

parent 44209861
......@@ -49,6 +49,7 @@ class GroupsController < ApplicationController
def people
@project = group.projects.find(params[:project_id]) if params[:project_id]
@users = @project ? @project.users : group.users
@users.sort_by!(&:name)
if @project
@team_member = @project.users_projects.new
......
......@@ -16,7 +16,7 @@ class SnippetsController < ProjectResourceController
respond_to :html
def index
@snippets = @project.snippets
@snippets = @project.snippets.fresh
end
def new
......
......@@ -25,6 +25,7 @@ class Project < ActiveRecord::Base
include PushObserver
include Authority
include Team
include NamespacedProject
class TransferError < StandardError; end
......@@ -178,7 +179,7 @@ class Project < ActiveRecord::Base
end
def repo_name
denied_paths = %w(gitolite-admin groups projects dashboard)
denied_paths = %w(gitolite-admin groups projects dashboard help )
if denied_paths.include?(path)
errors.add(:path, "like #{path} is not allowed")
......@@ -245,57 +246,11 @@ class Project < ActiveRecord::Base
gitlab_ci_service && gitlab_ci_service.active
end
def path_with_namespace
if namespace
namespace.path + '/' + path
else
path
end
end
# For compatibility with old code
def code
path
end
def transfer(new_namespace)
Project.transaction do
old_namespace = namespace
self.namespace = new_namespace
old_dir = old_namespace.try(:path) || ''
new_dir = new_namespace.try(:path) || ''
old_repo = if old_dir.present?
File.join(old_dir, self.path)
else
self.path
end
if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
raise TransferError.new("Project with same path in target namespace already exists")
end
Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
git_host.move_repository(old_repo, self)
save!
end
rescue Gitlab::ProjectMover::ProjectMoveError => ex
raise TransferError.new(ex.message)
end
def name_with_namespace
@name_with_namespace ||= begin
if namespace
namespace.human_name + " / " + name
else
name
end
end
end
def items_for entity
case entity
when 'issue' then
......@@ -304,16 +259,4 @@ class Project < ActiveRecord::Base
merge_requests
end
end
def namespace_owner
namespace.try(:owner)
end
def chief
if namespace
namespace_owner
else
owner
end
end
end
......@@ -56,7 +56,6 @@ class User < ActiveRecord::Base
has_many :issues, foreign_key: :author_id, dependent: :destroy
has_many :notes, foreign_key: :author_id, dependent: :destroy
has_many :merge_requests, foreign_key: :author_id, dependent: :destroy
has_many :my_own_projects, class_name: "Project", foreign_key: :owner_id
has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy
has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC"
has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy
......@@ -124,16 +123,4 @@ class User < ActiveRecord::Base
self.password = self.password_confirmation = Devise.friendly_token.first(8)
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
end
......@@ -105,4 +105,20 @@ module Account
def namespace_id
namespace.try :id
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
module NamespacedProject
def transfer(new_namespace)
Project.transaction do
old_namespace = namespace
self.namespace = new_namespace
old_dir = old_namespace.try(:path) || ''
new_dir = new_namespace.try(:path) || ''
old_repo = if old_dir.present?
File.join(old_dir, self.path)
else
self.path
end
if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
raise TransferError.new("Project with same path in target namespace already exists")
end
Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
git_host.move_repository(old_repo, self)
save!
end
rescue Gitlab::ProjectMover::ProjectMoveError => ex
raise TransferError.new(ex.message)
end
def name_with_namespace
@name_with_namespace ||= begin
if namespace
namespace.human_name + " / " + name
else
name
end
end
end
def namespace_owner
namespace.try(:owner)
end
def chief
if namespace
namespace_owner
else
owner
end
end
def path_with_namespace
if namespace
namespace.path + '/' + path
else
path
end
end
end
......@@ -19,20 +19,11 @@
.input
= text_field_tag :ppath, @project.path_to_repo, class: "xlarge", disabled: true
- unless project.new_record?
.clearfix
= f.label :namespace_id
.input
= f.select :namespace_id, namespaces_options(@project.namespace_id, :all), {}, {class: 'chosen'}
&nbsp;
%span.cred Be careful. Changing project namespace can have unintended side effects
- if project.repo_exists?
.clearfix
= f.label :default_branch, "Default Branch"
.input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
- unless project.new_record?
%fieldset.adv_settings
%legend Features:
......@@ -52,7 +43,20 @@
= f.label :wiki_enabled, "Wiki"
.input= f.check_box :wiki_enabled
- unless project.new_record?
%fieldset.features
%legend Transfer:
.control-group
= f.label :namespace_id do
%span Namespace
.controls
= f.select :namespace_id, namespaces_options(@project.namespace_id, :all), {}, {class: 'chosen'}
%br
%ul.prepend-top-10.cred
%li Be careful. Changing project namespace can have unintended side effects
%li You can transfer project only to namespaces you can manage
%li You will need to update your local repositories to point to the new location.
.actions
= f.submit 'Save Project', class: "btn save-btn"
= link_to 'Cancel', admin_projects_path, class: "btn cancel-btn"
......
%h3.page_title
Projects
Projects (#{@projects.count})
= link_to 'New Project', new_project_path, class: "btn small right"
%br
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
......
......@@ -47,21 +47,61 @@
%tr
%td
%b
Path:
Owned by:
%td
%code= @project.path_to_repo
- if @project.chief
= link_to @project.chief.name, admin_user_path(@project.chief)
- else
(deleted)
%tr
%td
%b
Created by:
%td
= @project.owner_name || '(deleted)'
%tr
%td
%b
Created at:
%td
= @project.created_at.stamp("March 1, 1999")
%table.zebra-striped
%thead
%tr
%th Repository
%th
%tr
%td
%b
FS Path:
%td
%code= @project.path_to_repo
%tr
%td
%b
Smart HTTP:
%td
= link_to @project.http_url_to_repo
%tr
%td
%b
SSH:
%td
= link_to @project.ssh_url_to_repo
%tr
%td
%b
Last commit at:
%td
= last_commit(@project)
%tr
%td
%b
Post Receive File:
%td
= check_box_tag :post_receive_file, 1, @project.has_post_receive_file?, disabled: true
%br
%h5
Team
......
%h3.page_title
Users
Users (#{@admin_users.count})
= link_to 'New User', new_admin_user_path, class: "btn small right"
%br
......@@ -40,6 +40,9 @@
%td= user.users_projects.count
%td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn small"
%td.bgred
- if user == current_user
%span.cred It's you!
- else
- if user.blocked
= link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success"
- else
......
......@@ -37,6 +37,12 @@
%b
Blocked:
%td= check_box_tag "blocked", 1, @admin_user.blocked, disabled: :disabled
%tr
%td
%b
Created at:
%td
= @admin_user.created_at.stamp("March 1, 1999")
%tr
%td
%b
......
......@@ -22,22 +22,21 @@
%hr
-if @hooks.any?
%h3
Hooks
%small (#{@hooks.count})
%h3.page_title
Hooks (#{@hooks.count})
%br
%table
%thead
%tr
%th URL
%th Method
%th
- @hooks.each do |hook|
%tr
%td
%span.badge.badge-info POST
= link_to project_hook_path(@project, hook) do
%strong= hook.url
= link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small right"
%td POST
%td
= link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small right"
.right
= link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small grouped"
= link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small grouped"
......@@ -9,3 +9,4 @@
$('.project_new_holder').show();
$("#new_project").replaceWith("#{escape_javascript(render('new_form'))}");
$('.save-project-loader').hide();
new Projects();
......@@ -17,7 +17,6 @@
= time_ago_in_words(note.created_at)
ago
- else
.alert-message.block-message
%span All files attached to project wall, issues etc will be displayed here
%p.slead All files attached to project wall, issues etc will be displayed here
%tr
%td
= image_tag gravatar_icon(snippet.author_email), class: "avatar s24"
%a{href: project_snippet_path(snippet.project, snippet)}
%strong= truncate(snippet.title, length: 60)
%td
......
= render "projects/project_head"
- if can? current_user, :write_snippet, @project
.alert-message.block-message
%h3.page_title
Snippets
%small share code pastes with others out of git repository
- if can? current_user, :write_snippet, @project
= link_to new_project_snippet_path(@project), class: "btn small add_new right", title: "New Snippet" do
Add new snippet
Share code pastes with others if it can't be in a git repository
%br
To add new snippet - click on button.
%br
%table
%thead
%tr
%th Title
%th File Name
%th Expires At
= render @snippets.fresh
- if @snippets.fresh.empty?
= render @snippets
- if @snippets.empty?
%tr
%td{colspan: 3}
%h3.nothing_here_message Nothing here.
......@@ -4,7 +4,7 @@
= Project.access_options.key(access).pluralize
%small= members.size
%ul.unstyled
- members.each do |up|
- members.sort_by(&:user_name).each do |up|
= render(partial: 'team_members/show', locals: {member: up})
......
......@@ -41,7 +41,6 @@ describe User do
it { should have_many(:users_projects).dependent(:destroy) }
it { should have_many(:projects) }
it { should have_many(:groups) }
it { should have_many(:my_own_projects).class_name('Project') }
it { should have_many(:keys).dependent(:destroy) }
it { should have_many(:events).class_name('Event').dependent(:destroy) }
it { should have_many(:recent_events).class_name('Event') }
......@@ -116,4 +115,16 @@ describe User do
user.authentication_token.should_not be_blank
end
end
describe 'projects and namespaces' do
before do
ActiveRecord::Base.observers.enable(:user_observer)
@user = create :user
@project = create :project, namespace: @user.namespace
end
it { @user.authorized_projects.should include(@project) }
it { @user.my_own_projects.should include(@project) }
it { @user.several_namespaces?.should be_false }
end
end
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