Commit fc6e2cdb authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' of dev.gitlab.org:gitlab/gitlab-ee

Conflicts:
	app/views/groups/_projects.html.haml
parents 3ac5a759 a6718222
Copyright (c) 2011 Dmitriy Zaporozhets
GitLab Enterprise Edition consists of two parts with distinct licenses.
All code exclusive to GitLab Enterprise Edition (EE) is covered by the
GitLab Enterprise Edition (EE) license. All code that is also released
in the GitLab Community Edition (CE) is covered by that license.
-------------------------------------------------------------------
The GitLab Enterprise Edition (EE) license
Copyright (c) 2013 GitLab.com
All Rights Reserved. No part of this software may be reproduced without
prior permission of GitLab.com. By using this software you agree to be
bound by the GitLab Enterprise Support Subscription Terms.
-------------------------------------------------------------------
The GitLab Community Edition (CE) license
Copyright (c) 2011-2013 Dmitriy Zaporozhets
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......
......@@ -34,6 +34,8 @@ class GroupsController < ApplicationController
@events = Event.in_projects(project_ids).limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push
@shared_projects = @group.shared_projects
respond_to do |format|
format.html
format.js
......
#-------------------------------------------------------------------
#
# The GitLab Enterprise Edition (EE) license
#
# Copyright (c) 2013 GitLab.com
#
# All Rights Reserved. No part of this software may be reproduced without
# prior permission of GitLab.com. By using this software you agree to be
# bound by the GitLab Enterprise Support Subscription Terms.
#
#-------------------------------------------------------------------
class Projects::GroupLinksController < Projects::ApplicationController
layout 'project_settings'
before_filter :authorize_admin_project!
def index
@group_links = project.project_group_links.all
@available_groups = Group.scoped
@available_groups -= project.invited_groups
@available_groups -= [project.group]
end
def create
link = project.project_group_links.new
link.group_id = params[:group_id]
link.save
redirect_to project_group_links_path(project)
end
def destroy
project.project_group_links.find(params[:id]).destroy
redirect_to project_group_links_path(project)
end
end
......@@ -16,6 +16,9 @@ class Group < Namespace
has_many :users_groups, dependent: :destroy
has_many :users, through: :users_groups
has_many :project_group_links, dependent: :destroy
has_many :shared_projects, through: :project_group_links, source: 'project'
after_create :add_owner
def human_name
......
......@@ -67,6 +67,9 @@ class Project < ActiveRecord::Base
has_many :deploy_keys_projects, dependent: :destroy
has_many :deploy_keys, through: :deploy_keys_projects
has_many :project_group_links, dependent: :destroy
has_many :invited_groups, through: :project_group_links, source: 'group'
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
......
#-------------------------------------------------------------------
#
# The GitLab Enterprise Edition (EE) license
#
# Copyright (c) 2013 GitLab.com
#
# All Rights Reserved. No part of this software may be reproduced without
# prior permission of GitLab.com. By using this software you agree to be
# bound by the GitLab Enterprise Support Subscription Terms.
#
#-------------------------------------------------------------------
class ProjectGroupLink < ActiveRecord::Base
GUEST = 10
REPORTER = 20
DEVELOPER = 30
MASTER = 40
belongs_to :project
belongs_to :group
validates :project_id, presence: true
validates :group_id, presence: true
validates :group_id, uniqueness: { scope: [:project_id], message: "already shared with this group" }
def self.access_options
{
"Guest" => GUEST,
"Reporter" => REPORTER,
"Developer" => DEVELOPER,
"Master" => MASTER
}
end
end
......@@ -111,13 +111,30 @@ class ProjectTeam
def fetch_members(level = nil)
project_members = project.users_projects
group_members = group ? group.users_groups : []
invited_members = []
if project.invited_groups.any?
project.invited_groups.each do |invited_group|
im = invited_group.users_groups
if level
if level == :masters
im = im.owners + im.masters
else
im = im.send(level)
end
end
invited_members << im
end
invited_members = invited_members.flatten.compact
end
if level
project_members = project_members.send(level)
group_members = group_members.send(level) if group
end
(project_members + group_members).map(&:user).uniq
(project_members + group_members + invited_members).map(&:user).uniq
end
def group
......
......@@ -242,8 +242,12 @@ class User < ActiveRecord::Base
# Projects user has access to
def authorized_projects
@authorized_projects ||= begin
project_ids = (owned_projects.pluck(:id) + groups_projects.pluck(:id) + projects.pluck(:id)).uniq
Project.where(id: project_ids).joins(:namespace).order('namespaces.name ASC')
project_ids = owned_projects.pluck(:id)
project_ids += groups_projects.pluck(:id)
project_ids += projects.pluck(:id)
project_ids += groups.joins(:shared_projects).pluck(:project_id)
Project.where(id: project_ids.uniq).joins(:namespace).order('namespaces.name ASC')
end
end
......
.ui-box
.title
%strong= @group.name
Projects (#{projects.count})
- if can? current_user, :manage_group, @group
%span.pull-right
= link_to new_project_path(namespace_id: @group.id), class: "btn" do
= link_to new_project_path(namespace_id: @group.id), class: "btn btn-small", title: 'New Project' do
%i.icon-plus
New Project
%span.only-wide New Project
%ul.well-list
- if projects.blank?
%p.nothing_here_message This groups has no projects yet
......
- if projects.present?
.ui-box
%h5.title
Projects shared with
%strong #{@group.name}
(#{projects.count})
%ul.well-list
- projects.each do |project|
%li.project-row
= link_to project_path(project), class: dom_class(project) do
%span.namespace-name
- if project.namespace
= project.namespace.human_name
\/
%span.project-name
= truncate(project.name, length: 25)
%span.arrow
%i.icon-angle-right
%span.last-activity
%span Last activity:
%span.date= project_last_activity(project)
......@@ -16,6 +16,9 @@
.description-block
= @group.description
= render "projects", projects: @projects
%br
= render "shared_projects", projects: @shared_projects
.prepend-top-20
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do
%strong
......
......@@ -7,6 +7,10 @@
= link_to project_team_index_path(@project), class: "team-tab tab" do
%i.icon-group
Members
= nav_link(controller: :group_links) do
= link_to project_group_links_path(@project) do
%span
Groups
= nav_link(controller: :deploy_keys) do
= link_to project_deploy_keys_path(@project) do
%span
......
%h3.page_title Share project with groups
%br
%p
Project can be stored in one group at once
%br
However you can share project with other groups here.
.row
.span5.enabled-groups
%h5
Already shared with:
%ul.bordered-list
- @group_links.each do |group_link|
- group = group_link.group
%li
%h5
.pull-left
= link_to project_group_link_path(@project, group_link), method: :delete, class: 'btn btn-small append-right-10' do
%i.icon-remove
= link_to group do
%i.icon-folder-open
= group.name
%small.light up to Masters
.span5.available-groups
%h5
Can be shared with:
%ul.bordered-list
- @available_groups.each do |group|
%li
%h5
.pull-right
= form_tag project_group_links_path(@project), method: :post do
= select_tag :group_access, options_for_select(ProjectGroupLink.access_options, ProjectGroupLink::MASTER), class: "span2"
= hidden_field_tag :group_id, group.id
= submit_tag "Share", class: "btn"
%i.icon-folder-close
= group.name
......@@ -289,6 +289,8 @@ Gitlab::Application.routes.draw do
end
end
resources :group_links, only: [:index, :create, :destroy]
resources :notes, only: [:index, :create, :destroy, :update] do
member do
delete :delete_attachment
......
class CreateProjectGroupLinks < ActiveRecord::Migration
def change
create_table :project_group_links do |t|
t.integer :project_id, null: false
t.integer :group_id, null: false
t.timestamps
end
end
end
FactoryGirl.define do
factory :project_group_link do
project
group
end
end
require 'spec_helper'
describe ProjectGroupLink do
describe "Associations" do
it { should belong_to(:group) }
it { should belong_to(:project) }
end
describe "Mass assignment" do
it { should_not allow_mass_assignment_of(:group_id) }
it { should_not allow_mass_assignment_of(:project_id) }
end
describe "Validation" do
let!(:project_group_link) { create(:project_group_link) }
it { should validate_presence_of(:project_id) }
it { should validate_uniqueness_of(:group_id).scoped_to(:project_id).with_message(/already shared/) }
it { should validate_presence_of(:group_id) }
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