Commit 439f399b authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Remove all team resources except models. Move models to deprecated directory

parent 670aaaeb
# Provides a base class for Admin controllers to subclass
#
# Automatically sets the layout and ensures an administrator is logged in
class Admin::Teams::ApplicationController < Admin::ApplicationController
private
def user_team
@team = UserTeam.find_by_path(params[:team_id])
end
end
class Admin::Teams::MembersController < Admin::Teams::ApplicationController
def new
@users = User.potential_team_members(user_team)
end
def create
unless params[:user_ids].blank?
user_ids = params[:user_ids]
access = params[:default_project_access]
is_admin = params[:group_admin]
user_team.add_members(user_ids, access, is_admin)
end
redirect_to admin_team_path(user_team), notice: 'Members were successfully added into Team of users.'
end
def edit
team_member
end
def update
options = {default_projects_access: params[:default_project_access], group_admin: params[:group_admin]}
if user_team.update_membership(team_member, options)
redirect_to admin_team_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users."
else
render :edit
end
end
def destroy
user_team.remove_member(team_member)
redirect_to admin_team_path(user_team), notice: "Member #{team_member.name} was successfully removed from Team of users."
end
protected
def team_member
@member ||= user_team.members.find_by_username(params[:id])
end
end
class Admin::Teams::ProjectsController < Admin::Teams::ApplicationController
def new
@projects = Project.scoped
@projects = @projects.without_team(user_team) if user_team.projects.any?
#@projects.reject!(&:empty_repo?)
end
def create
unless params[:project_ids].blank?
project_ids = params[:project_ids]
access = params[:greatest_project_access]
user_team.assign_to_projects(project_ids, access)
end
redirect_to admin_team_path(user_team), notice: 'Team of users was successfully assgned to projects.'
end
def edit
team_project
end
def update
if user_team.update_project_access(team_project, params[:greatest_project_access])
redirect_to admin_team_path(user_team), notice: 'Access was successfully updated.'
else
render :edit
end
end
def destroy
user_team.resign_from_project(team_project)
redirect_to admin_team_path(user_team), notice: 'Team of users was successfully reassigned from project.'
end
protected
def team_project
@project ||= user_team.projects.find_with_namespace(params[:id])
end
end
class Admin::TeamsController < Admin::ApplicationController
def index
@teams = UserTeam.order('name ASC')
@teams = @teams.search(params[:name]) if params[:name].present?
@teams = @teams.page(params[:page]).per(20)
end
def show
user_team
end
def new
@team = UserTeam.new
end
def edit
user_team
end
def create
@team = UserTeam.new(params[:user_team])
@team.path = @team.name.dup.parameterize if @team.name
@team.owner = current_user
if @team.save
redirect_to admin_team_path(@team), notice: 'Team of users was successfully created.'
else
render action: "new"
end
end
def update
user_team_params = params[:user_team].dup
owner_id = user_team_params.delete(:owner_id)
if owner_id
user_team.owner = User.find(owner_id)
end
if user_team.update_attributes(user_team_params)
redirect_to admin_team_path(user_team), notice: 'Team of users was successfully updated.'
else
render action: "edit"
end
end
def destroy
user_team.destroy
redirect_to admin_teams_path, notice: 'Team of users was successfully deleted.'
end
protected
def user_team
@team ||= UserTeam.find_by_path(params[:id])
end
end
......@@ -7,7 +7,6 @@ class DashboardController < ApplicationController
def show
@groups = current_user.authorized_groups.sort_by(&:human_name)
@has_authorized_projects = @projects.count > 0
@teams = current_user.authorized_teams
@projects_count = @projects.count
@projects = @projects.limit(20)
......
class Projects::TeamsController < Projects::ApplicationController
before_filter :authorize_admin_team_member!
def available
@teams = current_user.is_admin? ? UserTeam.scoped : current_user.user_teams
@teams = @teams.without_project(project)
unless @teams.any?
redirect_to project_team_index_path(project), notice: "No available teams for assigment."
end
end
def assign
unless params[:team_id].blank?
team = UserTeam.find(params[:team_id])
access = params[:greatest_project_access]
team.assign_to_project(project, access)
end
redirect_to project_team_index_path(project)
end
def resign
team = project.user_teams.find_by_path(params[:id])
team.resign_from_project(project)
redirect_to project_team_index_path(project)
end
protected
def user_team
@team ||= UserTeam.find_by_path(params[:id])
end
end
class Teams::ApplicationController < ApplicationController
layout 'user_team'
before_filter :authorize_manage_user_team!
protected
def user_team
@team ||= UserTeam.find_by_path(params[:team_id])
end
end
class Teams::MembersController < Teams::ApplicationController
skip_before_filter :authorize_manage_user_team!, only: [:index]
def index
@members = user_team.members
end
def new
@users = User.potential_team_members(user_team)
end
def create
unless params[:user_ids].blank?
user_ids = params[:user_ids].split(',')
access = params[:default_project_access]
is_admin = params[:group_admin]
user_team.add_members(user_ids, access, is_admin)
end
redirect_to team_members_path(user_team), notice: 'Members were successfully added into Team of users.'
end
def edit
team_member
end
def update
member_params = params[:team_member]
options = {
default_projects_access: member_params[:permission],
group_admin: member_params[:group_admin]
}
if user_team.update_membership(team_member, options)
redirect_to team_members_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users."
else
render :edit
end
end
def destroy
user_team.remove_member(team_member)
redirect_to team_path(user_team), notice: "Member #{team_member.name} was successfully removed from Team of users."
end
protected
def team_member
@member ||= user_team.members.find_by_username(params[:id])
end
end
class Teams::ProjectsController < Teams::ApplicationController
def create
redirect_to :back if params[:project_ids].blank?
project_ids = params[:project_ids]
access = params[:greatest_project_access]
# Reject non-allowed projects
allowed_project_ids = current_user.owned_projects.map(&:id)
project_ids.select! { |id| allowed_project_ids.include?(id.to_i) }
# Assign projects to team
user_team.assign_to_projects(project_ids, access)
redirect_to edit_team_path(user_team), notice: 'Team of users was successfully assigned to projects.'
end
def edit
team_project
end
def update
if user_team.update_project_access(team_project, params[:greatest_project_access])
redirect_to edit_team_path(user_team), notice: 'Access was successfully updated.'
else
render :edit
end
end
def destroy
user_team.resign_from_project(team_project)
redirect_to team_projects_path(user_team), notice: 'Team of users was successfully reassigned from project.'
end
private
def team_project
@project ||= user_team.projects.find_with_namespace(params[:id])
end
end
class TeamsController < ApplicationController
# Authorize
before_filter :authorize_create_team!, only: [:new, :create]
before_filter :authorize_manage_user_team!, only: [:edit, :update]
before_filter :authorize_admin_user_team!, only: [:destroy]
before_filter :user_team, except: [:new, :create]
layout :determine_layout
before_filter :set_title, only: [:new, :create]
def show
projects
@events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0)
end
def edit
projects
@avaliable_projects = current_user.owned_projects.without_team(user_team)
end
def update
if user_team.update_attributes(params[:user_team])
redirect_to team_path(user_team)
else
render action: :edit
end
end
def destroy
user_team.destroy
redirect_to dashboard_path
end
def new
@team = UserTeam.new
end
def create
@team = UserTeam.new(params[:user_team])
@team.owner = current_user unless params[:owner]
@team.path = @team.name.dup.parameterize if @team.name
if @team.save
# Add current user as Master to the team
@team.add_members([current_user.id], UsersProject::MASTER, true)
redirect_to team_path(@team)
else
render action: :new
end
end
# Get authored or assigned open merge requests
def merge_requests
projects
@merge_requests = MergeRequest.of_user_team(user_team)
@merge_requests = FilterContext.new(@merge_requests, params).execute
@merge_requests = @merge_requests.recent.page(params[:page]).per(20)
end
# Get only assigned issues
def issues
projects
@issues = Issue.of_user_team(user_team)
@issues = FilterContext.new(@issues, params).execute
@issues = @issues.recent.page(params[:page]).per(20)
@issues = @issues.includes(:author, :project)
end
protected
def projects
@projects ||= user_team.projects.sorted_by_activity
end
def user_team
@team ||= current_user.authorized_teams.find_by_path(params[:id])
end
def set_title
@title = 'New Team'
end
def determine_layout
if [:new, :create].include?(action_name.to_sym)
'navless'
else
'user_team'
end
end
end
......@@ -92,7 +92,6 @@ module ApplicationHelper
def search_autocomplete_source
projects = current_user.authorized_projects.map { |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } }
groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } }
teams = current_user.authorized_teams.map { |team| { label: "team: #{simple_sanitize(team.name)}", url: team_path(team) } }
default_nav = [
{ label: "My Profile", url: profile_path },
......@@ -128,7 +127,7 @@ module ApplicationHelper
]
end
[groups, teams, projects, default_nav, project_nav, help_nav].flatten.to_json
[groups, projects, default_nav, project_nav, help_nav].flatten.to_json
end
def emoji_autocomplete_source
......
module UserTeamsHelper
def team_filter_path(entity, options={})
exist_opts = {
status: params[:status],
project_id: params[:project_id],
}
options = exist_opts.merge(options)
case entity
when 'issue' then
issues_team_path(@team, options)
when 'merge_request'
merge_requests_team_path(@team, options)
end
end
def grouped_user_team_members(team)
team.user_team_user_relationships.sort_by(&:permission).reverse.group_by(&:permission)
end
def remove_from_user_team_message(team, member)
"You are going to remove #{member.name} from #{team.name}. Are you sure?"
end
end
......@@ -11,7 +11,6 @@ class Ability
when "PersonalSnippet" then personal_snippet_abilities(user, subject)
when "MergeRequest" then merge_request_abilities(user, subject)
when "Group", "Namespace" then group_abilities(user, subject)
when "UserTeam" then user_team_abilities(user, subject)
else []
end.concat(global_abilities(user))
end
......@@ -19,7 +18,6 @@ class Ability
def global_abilities(user)
rules = []
rules << :create_group if user.can_create_group
rules << :create_team if user.can_create_team
rules
end
......@@ -146,21 +144,6 @@ class Ability
rules.flatten
end
def user_team_abilities user, team
rules = []
# Only group owner and administrators can manage team
if user.admin? || team.owner == user || team.admin?(user)
rules << [ :manage_user_team ]
end
if team.owner == user || user.admin?
rules << [ :admin_user_team ]
end
rules.flatten
end
[:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name|
define_method "#{name}_abilities" do |user, subject|
if subject.author == user
......
......@@ -75,13 +75,6 @@ class User < ActiveRecord::Base
has_many :users_groups, dependent: :destroy
has_many :groups, through: :users_groups
# Teams
has_many :own_teams, dependent: :destroy, class_name: "UserTeam", foreign_key: :owner_id
has_many :user_team_user_relationships, dependent: :destroy
has_many :user_teams, through: :user_team_user_relationships
has_many :user_team_project_relationships, through: :user_teams
has_many :team_projects, through: :user_team_project_relationships
# Projects
has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
has_many :users_projects, dependent: :destroy
......@@ -235,10 +228,6 @@ class User < ActiveRecord::Base
own_groups
end
def owned_teams
own_teams
end
# Groups user has access to
def authorized_groups
@group_ids ||= (groups.pluck(:id) + own_groups.pluck(:id) + authorized_projects.pluck(:namespace_id))
......@@ -252,15 +241,6 @@ class User < ActiveRecord::Base
Project.where(id: @project_ids)
end
def authorized_teams
if admin?
UserTeam.scoped
else
@team_ids ||= (user_teams.pluck(:id) + own_teams.pluck(:id)).uniq
UserTeam.where(id: @team_ids)
end
end
# Team membership in authorized projects
def tm_in_authorized_projects
UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
......
......@@ -49,10 +49,6 @@
.span4
%h4 Stats
%hr
%p
Teams
%span.light.pull-right
= UserTeam.count
%p
Forks
%span.light.pull-right
......
%h3.page_title Edit Team
%hr
= form_for @team, url: admin_team_path(@team), method: :put do |f|
- if @team.errors.any?
.alert.alert-error
%span= @team.errors.full_messages.first
.clearfix.team_name_holder
= f.label :name do
Team name is
.input
= f.text_field :name, placeholder: "Example Team", class: "xxlarge"
.clearfix.team-description-holder
= f.label :description, "Details"
.input
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
.clearfix.team_name_holder
= f.label :path do
%span.cred Team path is
.input
= f.text_field :path, placeholder: "example-team", class: "xxlarge danger"
%ul.cred
%li It will change web url for access team and team projects.
.form-actions
= f.submit 'Edit team', class: "btn btn-remove"
= link_to 'Cancel', admin_teams_path, class: "btn btn-cancel"
%h3.page_title
Teams (#{@teams.total_count})
%small
allow you to organize groups of people that have a common focus. Use teams to simplify the process of assigning roles to groups of people.
= link_to 'New Team', new_admin_team_path, class: "btn btn-small pull-right"
%br
= form_tag admin_teams_path, method: :get, class: 'form-inline' do
= text_field_tag :name, params[:name], class: "span6"
= submit_tag "Search", class: "btn submit btn-primary"
%hr
%ul.bordered-list
- @teams.each do |team|
%li
.clearfix
.pull-right.prepend-top-10
= link_to 'Edit', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn btn-small"
= link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove"
%h4
= link_to admin_team_path(team) do
%i.icon-group
= team.name
.clearfix.light.append-bottom-10
%span
%b Owner:
- if team.owner
= link_to team.owner.name, admin_user_path(team.owner)
- else
(deleted)
\|
%span
%b Users:
%span.badge= team.members.count
\|
%span
%b Projects:
%span.badge= team.projects.count
.clearfix
%p
= truncate team.description, length: 150
= paginate @teams, theme: "gitlab"
= form_tag admin_team_member_path(@team, @member), method: :put do
-if @member.errors.any?
.alert.alert-error
%ul
- @member.errors.full_messages.each do |msg|
%li= msg
.clearfix
%label Default access for Team projects:
.input
= select_tag :default_project_access, options_for_select(UserTeam.access_roles, @team.default_projects_access(@member)), class: "project-access-select chosen span3"
.clearfix
%label Team admin?
.input
= check_box_tag :group_admin, true, @team.admin?(@member)
%br
.actions
= submit_tag 'Save', class: "btn btn-primary"
= link_to 'Cancel', :back, class: "btn"
%h3
Edit access #{@member.name} in #{@team.name} team
%hr
%table.zebra-striped
%tr
%td User:
%td= @member.name
%tr
%td Team:
%td= @team.name
%tr
%td Since:
%td= member_since(@team, @member).stamp("Nov 11, 2010")
= render 'form'
%h3.page_title
New members for
= link_to @team.name, admin_team_path(@team)
team
%hr
= form_tag admin_team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
- if @team.errors.any?
.alert.alert-error
%span= @team.errors.full_messages.first
.clearfix
= label_tag :user_ids do
Users to add
.input
= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name_with_username), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5'
.clearfix.group-description-holder
= label_tag :default_project_access do
Default permission in projects
.input
= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
.clearfix
= label_tag :group_admin do
Is team admin
.input
= check_box_tag :group_admin
.clearfix.form-actions
= submit_tag 'Add users into team', class: "btn btn-primary", id: :add_members_to_team
= link_to 'Cancel', :back, class: "btn"
%h3.page_title New Team
%hr
= form_for @team, url: admin_teams_path do |f|
- if @team.errors.any?
.alert.alert-error
%span= @team.errors.full_messages.first
.clearfix
= f.label :name do
Team name is
.input
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xxlarge left"
.clearfix.team-description-holder
= f.label :description, "Details"
.input
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
.form-actions
= f.submit 'Create team', class: "btn btn-create"
%hr
.padded
%ul
%li All created teams are public (users can view who enter into team and which project are assigned for this team)
%li People within a team see only projects they have access to
%li You will be able to assign existing projects for team
= form_tag admin_team_project_path(@team, @project), method: :put do
-if @project.errors.any?
.alert.alert-error
%ul
- @project.errors.full_messages.each do |msg|
%li= msg
.clearfix
%label Max access for Team members:
.input
= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles, @team.max_project_access(@project)), class: "project-access-select chosen span3"
%br
.actions
= submit_tag 'Save', class: "btn btn-primary"
= link_to 'Cancel', :back, class: "btn"
%h3
Edit max access in #{@project.name} for #{@team.name} team
%hr
%table.zebra-striped
%tr
%td Project:
%td= @project.name
%tr
%td Team:
%td= @team.name
%tr
%td Since:
%td= assigned_since(@team, @project).stamp("Nov 11, 2010")
= render 'form'
%h3.page_title
Team: #{@team.name}
%hr
= form_tag admin_team_projects_path(@team), id: "assign_projects", class: "bulk_import", method: :post do
%h6 Choose Projects you want to assign:
.clearfix
= label_tag :project_ids, "Projects"
.input
= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
%h6 Choose greatest user acces for your team in this projects:
.clearfix
= label_tag :greatest_project_access, "Greatest Access"
.input
= select_tag :greatest_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
.form-actions
= submit_tag 'Add team to projects', class: "btn btn-create", id: :assign_projects_to_team
%h3.page_title
Team: #{@team.name}
= link_to edit_admin_team_path(@team), class: "btn btn-small pull-right" do
%i.icon-edit
Edit
%hr
.row
.span6
.ui-box
%h5.title
Team info:
%ul.well-list
%li
%span.light Name:
%strong= @team.name
%li
%span.light Path:
%strong
= @team.path
%li
%span.light Description:
%strong
= @team.description
%li
%span.light Owned by:
%strong
- if @team.owner
= link_to @team.owner.name, admin_user_path(@team.owner)
- else
(deleted)
.pull-right
= link_to "#", class: "btn btn-small change-owner-link" do
%i.icon-edit
Change owner
%li.change-owner-holder.hide.bgred
.form-holder
%strong.cred New Owner:
= form_for @team, url: admin_team_path(@team) do |f|
= users_select_tag(:"user_team[owner_id]")
.prepend-top-10
= f.submit 'Change Owner', class: "btn btn-remove"
= link_to "Cancel", "#", class: "btn change-owner-cancel-link"
%li
%span.light Created at:
%strong
= @team.created_at.stamp("March 1, 1999")
.span6
.ui-box
%h5.title
Members (#{@team.members.count})
.pull-right
= link_to 'Add members', new_admin_team_member_path(@team), class: "btn btn-small", id: :add_members_to_team
%ul.well-list#members_list
- @team.members.each do |member|
%li.member{ class: "user_#{member.id}"}
= link_to [:admin, member] do
%strong
= member.name
.pull-right
%span.light
= @team.human_default_projects_access(member)
- if @team.admin?(member)
%span.label.label-info Admin
&nbsp;
= link_to 'Edit', edit_admin_team_member_path(@team, member), class: "btn btn-small"
&nbsp;
= link_to 'Remove', admin_team_member_path(@team, member), confirm: 'Remove member from team. Are you sure?', method: :delete, class: "btn btn-remove btn-small", id: "remove_member_#{member.id}"
.ui-box
%h5.title
Projects (#{@team.projects.count})
.pull-right
= link_to 'Add projects', new_admin_team_project_path(@team), class: "btn btn-small", id: :assign_projects_to_team
%ul.well-list#projects_list
- @team.projects.each do |project|
%li.project
= link_to [:admin, project] do
%strong
= project.name_with_namespace
.pull-right
%span.light
= @team.human_max_project_access(project)
&nbsp;
= link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn btn-small"
&nbsp;
= link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn btn-remove small", id: "relegate_project_#{project.id}"
......@@ -93,13 +93,6 @@
%li
%strong= link_to group.name, admin_group_path(group)
- if @admin_user.owned_teams.present?
.ui-box
%h5.title Owned teams:
%ul.well-list
- @admin_user.owned_teams.each do |team|
%li
%strong= link_to team.name, admin_team_path(team)
.span6
......
......@@ -3,16 +3,12 @@
= link_to 'Projects', '#projects', 'data-toggle' => 'tab', id: 'sidebar-projects-tab'
%li
= link_to 'Groups', '#groups', 'data-toggle' => 'tab', id: 'sidebar-groups-tab'
%li
= link_to 'Teams', '#teams', 'data-toggle' => 'tab', id: 'sidebar-teams-tab'
.tab-content
.tab-pane.active#projects
= render "projects", projects: @projects
.tab-pane#groups
= render "groups", groups: @groups
.tab-pane#teams
= render "teams", teams: @teams
.prepend-top-20
%span.rss-icon
......
......@@ -4,8 +4,6 @@
%i.icon-home
= nav_link(controller: :projects) do
= link_to "Projects", admin_projects_path
= nav_link(controller: :teams) do
= link_to "Teams", admin_teams_path
= nav_link(controller: :groups) do
= link_to "Groups", admin_groups_path
= nav_link(controller: :users) do
......
= render "projects/settings_nav"
%h3.page_title
= "Assign project to team of users"
%hr
%p.slead
Read more about assign to team of users #{link_to "here", '#', class: 'vlink'}.
= form_tag assign_project_teams_path(@project), method: 'post' do
%p.slead Choose Team of users you want to assign:
.padded
= label_tag :team_id, "Team"
.input= select_tag(:team_id, options_from_collection_for_select(@teams, :id, :name), prompt: "Select team", class: "chosen xxlarge", required: true)
%p.slead Choose greatest user acces in team you want to assign:
.padded
= label_tag :team_ids, "Permission"
.input= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles), {class: "project-access-select chosen span3" }
.actions
= submit_tag 'Assign', class: "btn btn-create"
= link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel"
= form_tag team_filter_path(entity), method: 'get' do
%fieldset.dashboard-search-filter
= search_field_tag "search", params[:search], { placeholder: 'Search', class: 'search-text-input' }
= button_tag type: 'submit', class: 'btn' do
%i.icon-search
%fieldset
%legend Status:
%ul.nav.nav-pills.nav-stacked
%li{class: ("active" if !params[:status])}
= link_to team_filter_path(entity, status: nil) do
Open
%li{class: ("active" if params[:status] == 'closed')}
= link_to team_filter_path(entity, status: 'closed') do
Closed
%li{class: ("active" if params[:status] == 'all')}
= link_to team_filter_path(entity, status: 'all') do
All
%fieldset
%legend Projects:
%ul.nav.nav-pills.nav-stacked
- @projects.each do |project|
- unless entities_per_project(project, entity).zero?
%li{class: ("active" if params[:project_id] == project.id.to_s)}
= link_to team_filter_path(entity, project_id: project.id) do
= project.name_with_namespace
%small.pull-right= entities_per_project(project, entity)
%fieldset
%hr
= link_to "Reset", team_filter_path(entity), class: 'btn pull-right'
.ui-box
%h5.title
Projects
%small
(#{projects.count})
- if can? current_user, :manage_user_team, @team
%span.pull-right
= link_to edit_team_path(@team), class: "btn btn-tiny info" do
%i.icon-plus
Assign Project
%ul.well-list
- if projects.blank?
%p.nothing_here_message This team has no projects yet
- projects.each do |project|
%li
= link_to project_path(project), class: dom_class(project) do
%strong.well-title= truncate(project.name_with_namespace, length: 40)
%span.arrow
&rarr;
%span.last_activity
%strong Last activity:
%span= project_last_activity(project)
.row
.span3
%ul.nav.nav-pills.nav-stacked
%li.active
= link_to 'Projects', '#tab-projects', 'data-toggle' => 'tab'
%li
= link_to 'Edit Team', '#tab-edit', 'data-toggle' => 'tab'
- if can? current_user, :admin_user_team, @team
%li
= link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab'
.span9
.tab-content
.tab-pane.active#tab-projects
.ui-box.projects-table
%h5.title Projects
%ul.well-list
- @projects.each do |project|
%li
- if project.public
%i.icon-share
- else
%i.icon-lock.cgreen
= link_to project.name_with_namespace, project
.pull-right
= link_to 'Edit max access', edit_team_project_path(@team, project), class: "btn btn-small"
= link_to 'Relegate', team_project_path(@team, project), confirm: 'Remove project from team and move to global namespace. Are you sure?', method: :delete, class: "btn btn-remove small"
.form-holder
= form_tag team_projects_path(@team), id: "assign_projects", class: "bulk_import", method: :post do
%table.headless
%tr
%td= select_tag :project_ids, options_from_collection_for_select(@avaliable_projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span4'
%td= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles), {class: "project-access-select chosen" }
%td= submit_tag 'Add Project', class: "btn btn-create", id: :assign_projects_to_team
.tab-pane#tab-edit
.ui-box
%h5.title Edit Team
%div.form-holder
= form_for @team, url: team_path(@team) do |f|
- if @team.errors.any?
.alert.alert-error
%span= @team.errors.full_messages.first
.clearfix
= f.label :name do
Team name is
.input
= f.text_field :name, placeholder: "Ex. OpenSource", class: "xlarge left"
.clearfix.team-description-holder
= f.label :description, "Details"
.input
= f.text_area :description, maxlength: 250, class: "xlarge js-gfm-input", rows: 4
.clearfix
= f.label :path do
Team path is
.input
= f.text_field :path, placeholder: "opensource", class: "xlarge left"
.form-actions
= f.submit 'Save team changes', class: "btn btn-primary"
.tab-pane#tab-remove
.ui-box.ui-box-danger
%h5.title Remove team
.ui-box-body
%p
Remove of team will cause removing members access to projects.
%p
%strong Removed team can not be restored!
= link_to 'Remove team', team_path(@team), method: :delete, confirm: "You are sure?", class: "btn btn-remove btn-small"
%h3.page_title
Issues
%small (in Team projects assigned to Team members)
%small.pull-right #{@issues.total_count} issues
%hr
.row
.span3
= render 'filter', entity: 'issue'
.span9
- if @issues.any?
- @issues.group_by(&:project).each do |group|
%div.ui-box
- @project = group[0]
%h5.title
= link_to_project @project
%ul.well-list.issues-list
- group[1].each do |issue|
= render issue
%hr
= paginate @issues, theme: "gitlab"
- else
%p.nothing_here_message Nothing to show here
= form_tag admin_team_member_path(@team, @member), method: :put do
-if @member.errors.any?
.alert.alert-error
%ul
- @member.errors.full_messages.each do |msg|
%li= msg
.clearfix
%label Default access for Team projects:
.input
= select_tag :default_project_access, options_for_select(UserTeam.access_roles, @team.default_projects_access(@member)), class: "project-access-select chosen span3"
.clearfix
%label Team admin?
.input
= check_box_tag :group_admin, true, @team.admin?(@member)
%br
.actions
= submit_tag 'Save', class: "btn btn-save"
= link_to 'Cancel', :back, class: "btn"
- user = member.user
- allow_admin = can? current_user, :manage_user_team, @team
%li{id: dom_id(member), class: "team_member_row user_#{user.id}"}
.row
.span3
= link_to user_path(user.username), title: user.name, class: "dark" do
= image_tag gravatar_icon(user.email, 40), class: "avatar s32"
= link_to user_path(user.username), title: user.name, class: "dark" do
%strong= truncate(user.name, lenght: 40)
%br
%small.cgray= user.username
.span5.pull-right
- if allow_admin
.pull-left
= form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f|
= label_tag :group_admin do
= f.check_box :group_admin, class: 'trigger-submit'
%span Admin access
&nbsp;
= f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "span2 trigger-submit"
.pull-right
- if current_user == user
%span.label.label-success This is you!
- if @team.owner == user
%span.label.label-info Owner
- elsif user.blocked?
%span.label.label-error Blocked
- elsif allow_admin
= link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
%i.icon-minus.icon-white
- grouped_user_team_members(team).each do |access, members|
- access_key = Project.access_options.key(access)
- next if params[:type].present? && params[:type] != access_key.tableize
.ui-box
%h5.title
= access_key.pluralize
%small= members.size
%ul.well-list.team-members
- members.sort_by(&:user_name).each do |member|
= render 'teams/members/member', member: member
%h3.page_title
Edit access #{@member.name} in #{@team.name} team
%hr
%table.zebra-striped
%tr
%td User:
%td= @member.name
%tr
%td Team:
%td= @team.name
%tr
%td Since:
%td= member_since(@team, @member).stamp("Nov 11, 2010")
= render 'form'
%h3.page_title
Team Members
(#{@members.count})
%small
Read more about project permissions
%strong= link_to "here", help_permissions_path, class: "vlink"
- if can? current_user, :manage_user_team, @team
%span.pull-right
= link_to new_team_member_path(@team), class: "btn btn-primary small grouped", title: "New Team Member" do
New Team Member
%hr
.row
.span3
%ul.nav.nav-pills.nav-stacked
%li{class: ("active" if !params[:type])}
= link_to team_members_path(@team, type: nil) do
All
%li{class: ("active" if params[:type] == 'masters')}
= link_to team_members_path(@team, type: 'masters') do
Masters
%li{class: ("active" if params[:type] == 'developers')}
= link_to team_members_path(@team, type: 'developers') do
Developers
%li{class: ("active" if params[:type] == 'reporters')}
= link_to team_members_path(@team, type: 'reporters') do
Reporters
%li{class: ("active" if params[:type] == 'guests')}
= link_to team_members_path(@team, type: 'guests') do
Guests
.span9
.clearfix
%div.team-table
= render "teams/members/team", team: @team
%h3.page_title
Team: #{@team.name}
%hr
= form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
%h6 1. Choose people you want in the team
.clearfix
= label_tag :user_ids, "People"
.input
= users_select_tag(:user_ids, multiple: true)
%h6 2. Set access level for them
.clearfix
= label_tag :project_access, "Project Access"
.input= select_tag :default_project_access, options_for_select(Project.access_options), class: "project-access-select chosen"
.clearfix
= label_tag :group_admin do
%span Team Admin?
.input= check_box_tag :group_admin
.actions
= submit_tag 'Add users', class: "btn btn-create", id: :add_members_to_team
= link_to "Cancel", team_members_path(@team), class: "btn btn-cancel"
%h3.page_title
Merge Requests
%small (authored by or assigned to Team members)
%small.pull-right #{@merge_requests.total_count} merge requests
%hr
.row
.span3
= render 'filter', entity: 'merge_request'
.span9
- if @merge_requests.any?
- @merge_requests.group_by(&:project).each do |group|
.ui-box
- @project = group[0]
%h5.title
= link_to_project @project
%ul.well-list
- group[1].each do |merge_request|
= render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
%hr
= paginate @merge_requests, theme: "gitlab"
- else
%h3.nothing_here_message Nothing to show here
= form_for @team, url: teams_path do |f|
- if @team.errors.any?
.alert.alert-error
%span= @team.errors.full_messages.first
.clearfix
= f.label :name do
Team name is
.input
= f.text_field :name, placeholder: "Ex. Ruby Developers", class: "xxlarge left"
.clearfix.team-description-holder
= f.label :description, "Details"
.input
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
.clearfix
.input
%ul
%li All created teams are public (users can view who enter into team and which project are assigned for this team)
%li People within a team see only projects they have access to
%li You will be able to assign existing projects for team
.form-actions
= f.submit 'Create team', class: "btn btn-create"
- if current_user.can_create_group?
.clearfix
.input.light
Need a group for several dependent projects?
= link_to new_group_path, class: "btn btn-tiny" do
Create a group
- if current_user.can_create_project?
.clearfix
.input.light
Want to create a project?
= link_to new_project_path, class: "btn btn-tiny" do
Create a project
= form_tag team_project_path(@team, @project), method: :put do
-if @project.errors.any?
.alert.alert-error
%ul
- @project.errors.full_messages.each do |msg|
%li= msg
.clearfix
%label Max access for Team members:
.input
= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles, @team.max_project_access(@project)), class: "project-access-select chosen span3"
%br
.actions
= submit_tag 'Save', class: "btn btn-save"
= link_to 'Cancel', :back, class: "btn btn-cancel"
%h3.page_title
Edit max access in #{link_to @project.name_with_namespace, @project} for #{link_to(@team.name, team_path(@team))} team
%hr
= render 'form'
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Team feed - #{@team.name}"
xml.link :href => team_url(@team, :atom), :rel => "self", :type => "application/atom+xml"
xml.link :href => team_url(@team), :rel => "alternate", :type => "text/html"
xml.id projects_url
xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any?
@events.each do |event|
if event.proper?
xml.entry do
event_link = event_feed_url(event)
event_title = event_feed_title(event)
xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}"
xml.link :href => event_link
xml.title truncate(event_title, :length => 80)
xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(event.author_email)
xml.author do |author|
xml.name event.author_name
xml.email event.author_email
end
xml.summary event_title
end
end
end
end
.dashboard
.activities.span8
= link_to dashboard_path, class: 'btn btn-tiny' do
&larr; To dashboard
&nbsp;
%span.cgray Events and projects are filtered in scope of team
%hr
- if @events.any?
.content_list
- else
%p.nothing_here_message Projects activity will be displayed here
.loading.hide
.side.span4
- if @team.description.present?
.description-block
= @team.description
= render "projects", projects: @projects
.prepend-top-20
= link_to team_path(@team, { format: :atom, private_token: current_user.private_token }), title: "Feed" do
%strong
%i.icon-rss
News Feed
%hr
= render 'shared/promo'
:plain
Pager.append(#{@events.count}, "#{escape_javascript(render(@events))}");
......@@ -155,20 +155,6 @@ Gitlab::Application.routes.draw do
resources :users_groups, only: [:create, :update, :destroy]
end
#
# Teams Area
#
resources :teams, constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} do
member do
get :issues
get :merge_requests
end
scope module: :teams do
resources :members, only: [:index, :new, :create, :edit, :update, :destroy]
resources :projects, only: [:index, :new, :create, :edit, :update, :destroy], constraints: { id: /[a-zA-Z.0-9_\-\/]+/ }
end
end
resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations }
......@@ -307,18 +293,6 @@ Gitlab::Application.routes.draw do
end
end
scope module: :projects do
resources :teams, only: [] do
collection do
get :available
post :assign
end
member do
delete :resign
end
end
end
resources :notes, only: [:index, :create, :destroy] do
collection do
post :preview
......
class Userteams < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedProject
include Select2Helper
When 'I do not have teams with me' do
UserTeam.with_member(current_user).destroy_all
end
Then 'I should see dashboard page without teams info block' do
page.has_no_css?(".teams-box").must_equal true
end
When 'I have teams with my membership' do
team = create :user_team, owner: current_user
team.add_member(current_user, UserTeam.access_roles["Master"], true)
end
Then 'I should see dashboard page with teams information block' do
page.should have_css(".teams-box")
end
When 'exist user teams' do
team = create :user_team
team.add_member(current_user, UserTeam.access_roles["Master"], true)
end
And 'I click on "All teams" link' do
click_link("All Teams")
end
Then 'I should see "All teams" page' do
current_path.should == teams_path
end
And 'I should see exist teams in teams list' do
team = UserTeam.last
find_in_list(".teams_list tr", team).must_equal true
end
When 'I click to "New team" link' do
click_link("New Team")
end
And 'I submit form with new team info' do
fill_in 'name', with: 'gitlab'
fill_in 'user_team_description', with: 'team description'
click_button 'Create team'
end
And 'I should see newly created team' do
page.should have_content "gitlab"
page.should have_content "team description"
end
Then 'I should be redirected to new team page' do
team = UserTeam.last
current_path.should == team_path(team)
end
When 'I have teams with projects and members' do
team = create :user_team, owner: current_user
@project = create :project
team.add_member(current_user, UserTeam.access_roles["Master"], true)
team.assign_to_project(@project, UserTeam.access_roles["Master"])
@event = create(:closed_issue_event, project: @project)
end
When 'I visit team page' do
visit team_path(UserTeam.last)
end
Then 'I should see projects list' do
within(".side .ui-box") do
page.should have_content(@project.name)
end
end
And 'project from team has issues assigned to me' do
team = UserTeam.last
team.projects.each do |project|
project.issues << create(:issue, assignee: current_user)
end
end
When 'I visit team issues page' do
team = UserTeam.last
visit issues_team_path(team)
end
Then 'I should see issues from this team assigned to me' do
team = UserTeam.last
team.projects.each do |project|
project.issues.assigned_to(current_user).each do |issue|
page.should have_content issue.title
end
end
end
Given 'I have team with projects and members' do
team = create :user_team, owner: current_user
project = create :project
user = create :user
team.add_member(current_user, UserTeam.access_roles["Master"], true)
team.add_member(user, UserTeam.access_roles["Developer"], false)
team.assign_to_project(project, UserTeam.access_roles["Master"])
end
Given 'project from team has issues assigned to teams members' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
project.issues << create(:issue, assignee: member)
end
end
end
Then 'I should see issues from this team assigned to teams members' do
team = UserTeam.last
team.projects.each do |project|
team.members.each do |member|
project.issues.assigned_to(member).each do |issue|
page.should have_content issue.title
end
end
end
end
Given 'project from team has merge requests assigned to me' do
team = UserTeam.last
team.projects.each do |project|
create(:merge_request, assignee: current_user, project: project)
end
end
When 'I visit team merge requests page' do
team = UserTeam.last
visit merge_requests_team_path(team)
end
Then 'I should see merge requests from this team assigned to me' do
team = UserTeam.last
team.projects.each do |project|
project.merge_requests.each do |merge_request|
page.should have_content merge_request.title
end
end
end
Given 'project from team has merge requests assigned to team members' do
team = UserTeam.last
team.projects.each do |project|
member = team.members.sample
create(:merge_request, assignee: member, project: project)
end
end
Given 'I have new user "John"' do
create :user, name: "John"
end
When 'I visit team people page' do
team = UserTeam.last
visit team_members_path(team)
end
And 'I select user "John" from list with role "Reporter"' do
user = User.find_by_name("John")
select2(user.id, from: "#user_ids", multiple: true)
within "#team_members" do
select "Reporter", from: "default_project_access"
end
click_button "Add"
end
Then 'I should see user "John" in team list' do
user = User.find_by_name("John")
team_members_list = find(".team-table")
team_members_list.should have_content user.name
end
And 'I have my own project without teams' do
@project = create :project, namespace: current_user.namespace
end
And 'I visit my team page' do
team = UserTeam.where(owner_id: current_user.id).last
visit team_path(team)
end
When 'I click on link "Assign Project"' do
click_link "Assign Project"
end
Then 'I should see form with my own project in available projects list' do
projects_select = find("#project_ids")
projects_select.should have_content(@project.name)
end
When 'I submit form with selected project and max access' do
within "#assign_projects" do
select @project.name_with_namespace, from: "project_ids"
select "Reporter", from: "greatest_project_access"
end
click_button "Add"
end
Then 'I should see my own project in team projects list' do
projects = find(".projects-table")
projects.should have_content(@project.name)
end
When 'I click link "New Team Member"' do
click_link "New Team Member"
end
protected
def current_team
@user_team ||= UserTeam.first
end
def project
current_team.projects.first
end
def assigned_to_user key, user
project.send(key).where(assignee_id: user)
end
def find_in_list(selector, item)
members_list = all(selector)
entered = false
members_list.each do |member_item|
entered = true if member_item.has_content?(item.name)
end
entered
end
end
Feature: UserTeams
Background:
Given I sign in as a user
And I own project "Shop"
And project "Shop" has push event
Scenario: I should see teams info block
When I have teams with my membership
And I visit dashboard page
Then I should see dashboard page with teams information block
Scenario: I should can create new team
When I have teams with my membership
And I visit dashboard page
When I click to "New team" link
And I submit form with new team info
Then I should be redirected to new team page
Then I should see newly created team
Scenario: I should see team dashboard list
When I have teams with projects and members
When I visit team page
Then I should see projects list
Scenario: I should see team issues list
Given I have team with projects and members
And project from team has issues assigned to me
When I visit team issues page
Then I should see issues from this team assigned to me
Scenario: I should see teams members issues list
Given I have team with projects and members
Given project from team has issues assigned to teams members
When I visit team issues page
Then I should see issues from this team assigned to teams members
Scenario: I should see team merge requests list
Given I have team with projects and members
Given project from team has merge requests assigned to me
When I visit team merge requests page
Then I should see merge requests from this team assigned to me
Scenario: I should see teams members merge requests list
Given I have team with projects and members
Given project from team has merge requests assigned to team members
When I visit team merge requests page
Then I should see merge requests from this team assigned to me
@javascript
Scenario: I should add user to projects in Team
Given I have team with projects and members
Given I have new user "John"
When I visit team people page
When I click link "New Team Member"
And I select user "John" from list with role "Reporter"
Then I should see user "John" in team list
Scenario: I should assign my team to my own project
Given I have team with projects and members
And I have my own project without teams
And I visit my team page
When I click on link "Assign Project"
Then I should see form with my own project in available projects list
When I submit form with selected project and max access
Then I should see my own project in team projects list
......@@ -35,7 +35,6 @@ module API
mount Notes
mount Internal
mount SystemHooks
mount UserTeams
mount ProjectSnippets
mount DeployKeys
mount ProjectHooks
......
......@@ -99,10 +99,6 @@ module API
expose :id, :title, :key, :created_at
end
class UserTeam < Grape::Entity
expose :id, :name, :path, :owner_id
end
class MergeRequest < Grape::Entity
expose :id, :target_branch, :source_branch, :project_id, :title, :state
expose :author, :assignee, using: Entities::UserBasic
......
module API
# user_teams API
class UserTeams < Grape::API
before { authenticate! }
resource :user_teams do
helpers do
def handle_team_member_errors(errors)
if errors[:permission].any?
render_api_error!(errors[:permission], 422)
end
not_found!
end
def validate_access_level?(level)
[UsersProject::GUEST, UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER].include? level.to_i
end
end
# Get a user_teams list
#
# Example Request:
# GET /user_teams
get do
if current_user.admin
@user_teams = paginate UserTeam
else
@user_teams = paginate current_user.user_teams
end
present @user_teams, with: Entities::UserTeam
end
# Create user_team. Available only for admin
#
# Parameters:
# name (required) - The name of the user_team
# path (required) - The path of the user_team
# Example Request:
# POST /user_teams
post do
authenticated_as_admin!
required_attributes! [:name, :path]
attrs = attributes_for_keys [:name, :path]
@user_team = UserTeam.new(attrs)
@user_team.owner = current_user
if @user_team.save
present @user_team, with: Entities::UserTeam
else
not_found!
end
end
# Get a single user_team
#
# Parameters:
# id (required) - The ID of a user_team
# Example Request:
# GET /user_teams/:id
get ":id" do
@user_team = UserTeam.find(params[:id])
if current_user.admin or current_user.user_teams.include? @user_team
present @user_team, with: Entities::UserTeam
else
not_found!
end
end
# Get user_team members
#
# Parameters:
# id (required) - The ID of a user_team
# Example Request:
# GET /user_teams/:id/members
get ":id/members" do
@user_team = UserTeam.find(params[:id])
if current_user.admin or current_user.user_teams.include? @user_team
@members = paginate @user_team.members
present @members, with: Entities::TeamMember, user_team: @user_team
else
not_found!
end
end
# Add a new user_team member
#
# Parameters:
# id (required) - The ID of a user_team
# user_id (required) - The ID of a user
# access_level (required) - Project access level
# Example Request:
# POST /user_teams/:id/members
post ":id/members" do
authenticated_as_admin!
required_attributes! [:user_id, :access_level]
if not validate_access_level?(params[:access_level])
render_api_error!("Wrong access level", 422)
end
@user_team = UserTeam.find(params[:id])
if @user_team
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
# Not existing member
if team_member.nil?
@user_team.add_member(params[:user_id], params[:access_level], false)
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
if team_member.nil?
render_api_error!("Error creating membership", 500)
else
@member = team_member.user
present @member, with: Entities::TeamMember, user_team: @user_team
end
else
render_api_error!("Already exists", 409)
end
else
not_found!
end
end
# Get a single team member from user_team
#
# Parameters:
# id (required) - The ID of a user_team
# user_id (required) - The ID of a team member
# Example Request:
# GET /user_teams/:id/members/:user_id
get ":id/members/:user_id" do
@user_team = UserTeam.find(params[:id])
if current_user.admin or current_user.user_teams.include? @user_team
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
unless team_member.nil?
present team_member.user, with: Entities::TeamMember, user_team: @user_team
else
not_found!
end
else
not_found!
end
end
# Remove a team member from user_team
#
# Parameters:
# id (required) - The ID of a user_team
# user_id (required) - The ID of a team member
# Example Request:
# DELETE /user_teams/:id/members/:user_id
delete ":id/members/:user_id" do
authenticated_as_admin!
@user_team = UserTeam.find(params[:id])
if @user_team
team_member = @user_team.user_team_user_relationships.find_by_user_id(params[:user_id])
unless team_member.nil?
team_member.destroy
else
not_found!
end
else
not_found!
end
end
# Get to user_team assigned projects
#
# Parameters:
# id (required) - The ID of a user_team
# Example Request:
# GET /user_teams/:id/projects
get ":id/projects" do
@user_team = UserTeam.find(params[:id])
if current_user.admin or current_user.user_teams.include? @user_team
@projects = paginate @user_team.projects
present @projects, with: Entities::TeamProject, user_team: @user_team
else
not_found!
end
end
# Add a new user_team project
#
# Parameters:
# id (required) - The ID of a user_team
# project_id (required) - The ID of a project
# greatest_access_level (required) - Project access level
# Example Request:
# POST /user_teams/:id/projects
post ":id/projects" do
authenticated_as_admin!
required_attributes! [:project_id, :greatest_access_level]
if not validate_access_level?(params[:greatest_access_level])
render_api_error!("Wrong greatest_access_level", 422)
end
@user_team = UserTeam.find(params[:id])
if @user_team
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
# No existing project
if team_project.nil?
@user_team.assign_to_projects([params[:project_id]], params[:greatest_access_level])
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
if team_project.nil?
render_api_error!("Error creating project assignment", 500)
else
@project = team_project.project
present @project, with: Entities::TeamProject, user_team: @user_team
end
else
render_api_error!("Already exists", 409)
end
else
not_found!
end
end
# Show a single team project from user_team
#
# Parameters:
# id (required) - The ID of a user_team
# project_id (required) - The ID of a project assigned to the team
# Example Request:
# GET /user_teams/:id/projects/:project_id
get ":id/projects/:project_id" do
@user_team = UserTeam.find(params[:id])
if current_user.admin or current_user.user_teams.include? @user_team
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
unless team_project.nil?
present team_project.project, with: Entities::TeamProject, user_team: @user_team
else
not_found!
end
else
not_found!
end
end
# Remove a team project from user_team
#
# Parameters:
# id (required) - The ID of a user_team
# project_id (required) - The ID of a project assigned to the team
# Example Request:
# DELETE /user_teams/:id/projects/:project_id
delete ":id/projects/:project_id" do
authenticated_as_admin!
@user_team = UserTeam.find(params[:id])
if @user_team
team_project = @user_team.user_team_project_relationships.find_by_project_id(params[:project_id])
unless team_project.nil?
team_project.destroy
else
not_found!
end
else
not_found!
end
end
end
end
end
# UserTeamManager class
#
# Used for manage User teams with project repositories
module Gitlab
class UserTeamManager
class << self
def assign(team, project, access)
project = Project.find(project) unless project.is_a? Project
searched_project = team.user_team_project_relationships.find_by_project_id(project.id)
unless searched_project.present?
team.user_team_project_relationships.create(project_id: project.id, greatest_access: access)
update_team_users_access_in_project(team, project, :added)
end
end
def resign(team, project)
project = Project.find(project) unless project.is_a? Project
team.user_team_project_relationships.with_project(project).destroy_all
update_team_users_access_in_project(team, project, :updated)
end
def update_team_user_membership(team, member, options)
updates = {}
if options[:default_projects_access].present?
default_projects_access = options[:default_projects_access].to_s
if default_projects_access != team.default_projects_access(member).to_s
updates[:permission] = default_projects_access
end
end
if options[:group_admin].present?
group_admin = options[:group_admin].to_s == "1" ? true : false
if group_admin != team.admin?(member)
updates[:group_admin] = group_admin
end
end
return true if updates.blank?
user_team_relationship = team.user_team_user_relationships.find_by_user_id(member)
return false unless user_team_relationship.update_attributes(updates)
rebuild_project_permissions_to_member(team, member) if updates[:permission]
true
end
def update_project_greates_access(team, project, permission)
project_relation = team.user_team_project_relationships.find_by_project_id(project)
if permission != team.max_project_access(project)
if project_relation.update_attributes(greatest_access: permission)
update_team_users_access_in_project(team, project, :updated)
true
else
false
end
else
true
end
end
def rebuild_project_permissions_to_member(team, member)
team.projects.each do |project|
update_team_user_access_in_project(team, member, project, :updated)
end
end
def update_team_users_access_in_project(team, project, action)
members = team.members
members.each do |member|
update_team_user_access_in_project(team, member, project, action)
end
end
def update_team_user_access_in_project(team, user, project, action)
granted_access = max_teams_member_permission_in_project(user, project, action)
project_team_user = UsersProject.find_by_user_id_and_project_id(user.id, project.id)
if granted_access.zero?
project_team_user.destroy if project_team_user.present?
return
end
if project_team_user.present?
project_team_user.update_attributes(project_access: granted_access)
else
project.team << [user, granted_access]
end
end
def max_teams_member_permission_in_project(user, project, action = nil, teams = nil)
result_access = 0
teams ||= project.user_teams.with_member(user)
if action && (action == :added)
result_access = project.users_projects.with_user(user).first.project_access if project.users_projects.with_user(user).any?
end
if teams.any?
teams.each do |team|
granted_access = max_team_member_permission_in_project(team, user, project)
result_access = [granted_access, result_access].max
end
end
result_access
end
def max_team_member_permission_in_project(team, user, project)
member_access = team.default_projects_access(user)
team_access = team.user_team_project_relationships.find_by_project_id(project.id).greatest_access
[team_access, member_access].min
end
def add_member_into_team(team, user, access, admin)
user = User.find(user) unless user.is_a? User
team.user_team_user_relationships.create(user_id: user.id, permission: access, group_admin: admin)
team.projects.each do |project|
update_team_user_access_in_project(team, user, project, :added)
end
end
def remove_member_from_team(team, user)
user = User.find(user) unless user.is_a? User
team.user_team_user_relationships.with_user(user).destroy_all
other_teams = []
team.projects.each do |project|
other_teams << project.user_teams.with_member(user)
end
other_teams.uniq
unless other_teams.any?
UsersProject.in_projects(team.projects).with_user(user).destroy_all
end
end
end
end
end
# == Schema Information
#
# Table name: user_team_project_relationships
#
# id :integer not null, primary key
# project_id :integer
# user_team_id :integer
# greatest_access :integer
# created_at :datetime not null
# updated_at :datetime not null
#
require 'spec_helper'
describe UserTeamProjectRelationship do
pending "add some examples to (or delete) #{__FILE__}"
end
# == Schema Information
#
# Table name: user_teams
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# owner_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# description :string(255) default(""), not null
#
require 'spec_helper'
describe UserTeam do
let(:team) { FactoryGirl.create :user_team }
context ".add_member" do
let(:user) { FactoryGirl.create :user }
it "should work" do
team.add_member(user, UsersProject::DEVELOPER, false)
team.members.should include(user)
end
end
context ".remove_member" do
let(:user) { FactoryGirl.create :user }
before { team.add_member(user, UsersProject::DEVELOPER, false) }
it "should work" do
team.remove_member(user)
team.members.should_not include(user)
end
end
end
# == Schema Information
#
# Table name: user_team_user_relationships
#
# id :integer not null, primary key
# user_id :integer
# user_team_id :integer
# group_admin :boolean
# permission :integer
# created_at :datetime not null
# updated_at :datetime not null
#
require 'spec_helper'
describe UserTeamUserRelationship do
pending "add some examples to (or delete) #{__FILE__}"
end
require 'spec_helper'
describe API::API do
include ApiHelpers
# Create test objects
let(:user1) { create(:user) }
let(:user2) { create(:user) }
let(:admin) { create(:admin) }
let!(:group1) { create(:group, owner: user1) }
let!(:group2) { create(:group, owner: user2) }
let(:user_team1) { create(:user_team, owner: user1) }
let(:user_team2) { create(:user_team, owner: user2) }
let!(:project1) { create(:project, creator_id: admin.id) }
let!(:project2) { create(:project, creator_id: admin.id) }
before {
# Add members to teams
user_team1.add_member(user1, UsersProject::MASTER, false)
user_team2.add_member(user2, UsersProject::MASTER, false)
# Add projects to teams
user_team1.assign_to_projects([project1.id], UsersProject::MASTER)
user_team2.assign_to_projects([project2.id], UsersProject::MASTER)
}
describe "GET /user_teams" do
context "when unauthenticated" do
it "should return authentication error" do
get api("/user_teams")
response.status.should == 401
end
end
context "when authenticated as user" do
it "normal user: should return an array of user_teams of user1" do
get api("/user_teams", user1)
response.status.should == 200
json_response.should be_an Array
json_response.length.should == 1
json_response.first['name'].should == user_team1.name
end
end
context "when authenticated as admin" do
it "admin: should return an array of all user_teams" do
get api("/user_teams", admin)
response.status.should == 200
json_response.should be_an Array
json_response.length.should == 2
end
end
end
describe "GET /user_teams/:id" do
context "when authenticated as user" do
it "should return one of user1's user_teams" do
get api("/user_teams/#{user_team1.id}", user1)
response.status.should == 200
json_response['name'] == user_team1.name
end
it "should not return a non existing team" do
get api("/user_teams/1328", user1)
response.status.should == 404
end
it "should not return a user_team not attached to user1" do
get api("/user_teams/#{user_team2.id}", user1)
response.status.should == 404
end
end
context "when authenticated as admin" do
it "should return any existing user_team" do
get api("/user_teams/#{user_team2.id}", admin)
response.status.should == 200
json_response['name'].should == user_team2.name
end
it "should not return a non existing user_team" do
get api("/user_teams/1328", admin)
response.status.should == 404
end
end
end
describe "POST /user_teams" do
context "when authenticated as user" do
it "should not create user_team" do
count_before=UserTeam.count
post api("/user_teams", user1), attributes_for(:user_team)
response.status.should == 403
UserTeam.count.should == count_before
end
end
context "when authenticated as admin" do
it "should create user_team" do
count_before=UserTeam.count
post api("/user_teams", admin), attributes_for(:user_team)
response.status.should == 201
UserTeam.count.should == count_before + 1
end
it "should not create user_team, duplicate" do
post api("/user_teams", admin), {:name => "Duplicate Test", :path => user_team2.path}
response.status.should == 404
end
it "should return 400 bad request error if name not given" do
post api("/user_teams", admin), {:path => user_team2.path}
response.status.should == 400
end
it "should return 400 bad request error if path not given" do
post api("/user_teams", admin), {:name => 'test'}
response.status.should == 400
end
end
end
# Members
describe "GET /user_teams/:id/members" do
context "when authenticated as user" do
it "should return user1 as member of user1's user_teams" do
get api("/user_teams/#{user_team1.id}/members", user1)
response.status.should == 200
json_response.first['name'].should == user1.name
json_response.first['access_level'].should == UsersProject::MASTER
end
end
context "when authenticated as admin" do
it "should return member of any existing user_team" do
get api("/user_teams/#{user_team2.id}/members", admin)
response.status.should == 200
json_response.first['name'].should == user2.name
json_response.first['access_level'].should == UsersProject::MASTER
end
end
end
describe "POST /user_teams/:id/members" do
context "when authenticated as user" do
it "should not add user2 as member of user_team1" do
post api("/user_teams/#{user_team1.id}/members", user1), user_id: user2.id, access_level: UsersProject::MASTER
response.status.should == 403
end
end
context "when authenticated as admin" do
it "should return ok and add new member" do
count_before=user_team1.user_team_user_relationships.count
post api("/user_teams/#{user_team1.id}/members", admin), user_id: user2.id, access_level: UsersProject::MASTER
response.status.should == 201
json_response['name'].should == user2.name
json_response['access_level'].should == UsersProject::MASTER
user_team1.user_team_user_relationships.count.should == count_before + 1
end
it "should return ok if member already exists" do
post api("/user_teams/#{user_team2.id}/members", admin), user_id: user2.id, access_level: UsersProject::MASTER
response.status.should == 409
end
it "should return a 400 error when user id is not given" do
post api("/user_teams/#{user_team2.id}/members", admin), access_level: UsersProject::MASTER
response.status.should == 400
end
it "should return a 400 error when access level is not given" do
post api("/user_teams/#{user_team2.id}/members", admin), user_id: user2.id
response.status.should == 400
end
it "should return a 422 error when access level is not known" do
post api("/user_teams/#{user_team2.id}/members", admin), user_id: user1.id, access_level: 1234
response.status.should == 422
end
end
end
# Get single member
describe "GET /user_teams/:id/members/:user_id" do
context "when authenticated as member" do
it "should show user1's membership of user_team1" do
get api("/user_teams/#{user_team1.id}/members/#{user1.id}", user1)
response.status.should == 200
json_response['name'].should == user1.name
json_response['access_level'].should == UsersProject::MASTER
end
it "should show that user2 is not member of user_team1" do
get api("/user_teams/#{user_team1.id}/members/#{user2.id}", user1)
response.status.should == 404
end
end
context "when authenticated as non-member" do
it "should not show user1's membership of user_team1" do
get api("/user_teams/#{user_team1.id}/members/#{user1.id}", user2)
response.status.should == 404
end
end
context "when authenticated as admin" do
it "should show user1's membership of user_team1" do
get api("/user_teams/#{user_team1.id}/members/#{user1.id}", admin)
response.status.should == 200
json_response['name'].should == user1.name
json_response['access_level'].should == UsersProject::MASTER
end
it "should return a 404 error when user id is not known" do
get api("/user_teams/#{user_team2.id}/members/1328", admin)
response.status.should == 404
end
end
end
describe "DELETE /user_teams/:id/members/:user_id" do
context "when authenticated as user" do
it "should not delete user1's membership of user_team1" do
delete api("/user_teams/#{user_team1.id}/members/#{user1.id}", user1)
response.status.should == 403
end
end
context "when authenticated as admin" do
it "should delete user1's membership of user_team1" do
count_before=user_team1.user_team_user_relationships.count
delete api("/user_teams/#{user_team1.id}/members/#{user1.id}", admin)
response.status.should == 200
user_team1.user_team_user_relationships.count.should == count_before - 1
end
it "should return a 404 error when user id is not known" do
delete api("/user_teams/#{user_team2.id}/members/1328", admin)
response.status.should == 404
end
end
end
# Projects
describe "GET /user_teams/:id/projects" do
context "when authenticated as user" do
it "should return project1 as assigned to user_team1 as member user1" do
get api("/user_teams/#{user_team1.id}/projects", user1)
response.status.should == 200
json_response.first['name'].should == project1.name
json_response.length.should == user_team1.user_team_project_relationships.count
end
end
context "when authenticated as admin" do
it "should return project2 as assigned to user_team2 as non-member, but admin" do
get api("/user_teams/#{user_team2.id}/projects", admin)
response.status.should == 200
json_response.first['name'].should == project2.name
json_response.first['greatest_access_level'].should == UsersProject::MASTER
end
end
end
describe "POST /user_teams/:id/projects" do
context "when authenticated as admin" do
it "should return ok and add new project" do
count_before=user_team1.user_team_project_relationships.count
post api("/user_teams/#{user_team1.id}/projects", admin),
project_id: project2.id,
greatest_access_level: UsersProject::MASTER
response.status.should == 201
json_response['name'].should == project2.name
json_response['greatest_access_level'].should == UsersProject::MASTER
user_team1.user_team_project_relationships.count.should == count_before + 1
end
it "should return ok if project already exists" do
post api("/user_teams/#{user_team2.id}/projects", admin),
project_id: project2.id,
greatest_access_level: UsersProject::MASTER
response.status.should == 409
end
it "should return a 400 error when project id is not given" do
post api("/user_teams/#{user_team2.id}/projects", admin), greatest_access_level: UsersProject::MASTER
response.status.should == 400
end
it "should return a 400 error when access level is not given" do
post api("/user_teams/#{user_team2.id}/projects", admin), project_id: project2.id
response.status.should == 400
end
it "should return a 422 error when access level is not known" do
post api("/user_teams/#{user_team2.id}/projects", admin),
project_id: project2.id,
greatest_access_level: 1234
response.status.should == 422
end
end
end
describe "GET /user_teams/:id/projects/:project_id" do
context "when authenticated as member" do
it "should show project1's assignment to user_team1" do
get api("/user_teams/#{user_team1.id}/projects/#{project1.id}", user1)
response.status.should == 200
json_response['name'].should == project1.name
json_response['greatest_access_level'].should == UsersProject::MASTER
end
it "should show project2's is not assigned to user_team1" do
get api("/user_teams/#{user_team1.id}/projects/#{project2.id}", user1)
response.status.should == 404
end
end
context "when authenticated as non-member" do
it "should not show project1's assignment to user_team1" do
get api("/user_teams/#{user_team1.id}/projects/#{project1.id}", user2)
response.status.should == 404
end
end
context "when authenticated as admin" do
it "should show project1's assignment to user_team1" do
get api("/user_teams/#{user_team1.id}/projects/#{project1.id}", admin)
response.status.should == 200
json_response['name'].should == project1.name
json_response['greatest_access_level'].should == UsersProject::MASTER
end
it "should return a 404 error when project id is not known" do
get api("/user_teams/#{user_team2.id}/projects/1328", admin)
response.status.should == 404
end
end
end
describe "DELETE /user_teams/:id/projects/:project_id" do
context "when authenticated as user" do
it "should not delete project1's assignment to user_team2" do
delete api("/user_teams/#{user_team2.id}/projects/#{project1.id}", user1)
response.status.should == 403
end
end
context "when authenticated as admin" do
it "should delete project1's assignment to user_team1" do
count_before=user_team1.user_team_project_relationships.count
delete api("/user_teams/#{user_team1.id}/projects/#{project1.id}", admin)
response.status.should == 200
user_team1.user_team_project_relationships.count.should == count_before - 1
end
it "should return a 404 error when project id is not known" do
delete api("/user_teams/#{user_team2.id}/projects/1328", admin)
response.status.should == 404
end
end
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