Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
30d2d238
Commit
30d2d238
authored
Jun 18, 2013
by
Dmitriy Zaporozhets
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/users_groups' into 6-0-dev
parents
cc5440e8
60bb3516
Changes
41
Show whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
396 additions
and
252 deletions
+396
-252
app/assets/javascripts/dispatcher.js.coffee
app/assets/javascripts/dispatcher.js.coffee
+2
-0
app/assets/javascripts/groups.js.coffee
app/assets/javascripts/groups.js.coffee
+6
-0
app/assets/stylesheets/gitlab_bootstrap/lists.scss
app/assets/stylesheets/gitlab_bootstrap/lists.scss
+6
-0
app/controllers/admin/groups_controller.rb
app/controllers/admin/groups_controller.rb
+1
-3
app/controllers/dashboard_controller.rb
app/controllers/dashboard_controller.rb
+3
-2
app/controllers/graphs_controller.rb
app/controllers/graphs_controller.rb
+1
-1
app/controllers/groups_controller.rb
app/controllers/groups_controller.rb
+4
-15
app/controllers/issues_controller.rb
app/controllers/issues_controller.rb
+1
-1
app/controllers/team_members_controller.rb
app/controllers/team_members_controller.rb
+2
-4
app/controllers/users_controller.rb
app/controllers/users_controller.rb
+1
-1
app/controllers/users_groups_controller.rb
app/controllers/users_groups_controller.rb
+40
-0
app/helpers/groups_helper.rb
app/helpers/groups_helper.rb
+4
-0
app/models/ability.rb
app/models/ability.rb
+5
-1
app/models/group.rb
app/models/group.rb
+16
-14
app/models/project_team.rb
app/models/project_team.rb
+33
-5
app/models/user.rb
app/models/user.rb
+6
-4
app/models/users_group.rb
app/models/users_group.rb
+42
-0
app/models/users_project.rb
app/models/users_project.rb
+1
-3
app/services/system_hooks_service.rb
app/services/system_hooks_service.rb
+1
-1
app/views/admin/groups/show.html.haml
app/views/admin/groups/show.html.haml
+20
-19
app/views/groups/_new_group_member.html.haml
app/views/groups/_new_group_member.html.haml
+7
-7
app/views/groups/_new_member.html.haml
app/views/groups/_new_member.html.haml
+0
-18
app/views/groups/_people_filter.html.haml
app/views/groups/_people_filter.html.haml
+0
-16
app/views/groups/people.html.haml
app/views/groups/people.html.haml
+15
-15
app/views/issues/_form.html.haml
app/views/issues/_form.html.haml
+1
-1
app/views/issues/_issues.html.haml
app/views/issues/_issues.html.haml
+2
-2
app/views/projects/_settings_nav.html.haml
app/views/projects/_settings_nav.html.haml
+1
-1
app/views/team_members/_group_members.html.haml
app/views/team_members/_group_members.html.haml
+10
-0
app/views/team_members/_team.html.haml
app/views/team_members/_team.html.haml
+6
-7
app/views/team_members/_team_member.html.haml
app/views/team_members/_team_member.html.haml
+12
-22
app/views/team_members/index.html.haml
app/views/team_members/index.html.haml
+20
-41
app/views/users_groups/_users_group.html.haml
app/views/users_groups/_users_group.html.haml
+16
-0
config/routes.rb
config/routes.rb
+2
-2
db/migrate/20130617095603_create_users_groups.rb
db/migrate/20130617095603_create_users_groups.rb
+11
-0
db/schema.rb
db/schema.rb
+41
-37
features/steps/admin/admin_groups.rb
features/steps/admin/admin_groups.rb
+1
-1
features/steps/group/group.rb
features/steps/group/group.rb
+3
-3
features/steps/project/project_active_tab.rb
features/steps/project/project_active_tab.rb
+2
-2
features/steps/project/project_team_management.rb
features/steps/project/project_team_management.rb
+17
-3
spec/factories/users_groups.rb
spec/factories/users_groups.rb
+7
-0
spec/models/users_group_spec.rb
spec/models/users_group_spec.rb
+27
-0
No files found.
app/assets/javascripts/dispatcher.js.coffee
View file @
30d2d238
...
...
@@ -32,6 +32,8 @@ class Dispatcher
new
Wall
(
project_id
)
when
'teams:members:index'
new
TeamMembers
()
when
'groups:people'
new
GroupMembers
()
switch
path
.
first
()
when
'admin'
then
new
Admin
()
...
...
app/assets/javascripts/groups.js.coffee
0 → 100644
View file @
30d2d238
class
GroupMembers
constructor
:
->
$
(
'li.users_group'
).
bind
'ajax:success'
,
->
$
(
this
).
fadeOut
()
@
GroupMembers
=
GroupMembers
app/assets/stylesheets/gitlab_bootstrap/lists.scss
View file @
30d2d238
...
...
@@ -16,6 +16,12 @@
color
:
#888
;
}
&
.unstyled
{
&
:hover
{
background
:
none
;
}
}
&
.smoke
{
background-color
:
#f5f5f5
;
}
&
:hover
{
...
...
app/controllers/admin/groups_controller.rb
View file @
30d2d238
...
...
@@ -66,14 +66,12 @@ class Admin::GroupsController < Admin::ApplicationController
end
def
project_teams_update
@group
.
add_users
_to_project_teams
(
params
[
:user_ids
].
split
(
','
),
params
[
:project
_access
])
@group
.
add_users
(
params
[
:user_ids
].
split
(
','
),
params
[
:group
_access
])
redirect_to
[
:admin
,
@group
],
notice:
'Users were successfully added.'
end
def
destroy
@group
.
truncate_teams
@group
.
destroy
redirect_to
admin_groups_path
,
notice:
'Group was successfully deleted.'
...
...
app/controllers/dashboard_controller.rb
View file @
30d2d238
...
...
@@ -34,11 +34,12 @@ class DashboardController < ApplicationController
@projects
end
@projects
=
@projects
.
tagged_with
(
params
[
:label
])
if
params
[
:label
].
present?
@projects
=
@projects
.
search
(
params
[
:search
])
if
params
[
:search
].
present?
@projects
=
@projects
.
page
(
params
[
:page
]).
per
(
30
)
@labels
=
Project
.
where
(
id:
@projects
.
map
(
&
:id
)).
tags_on
(
:labels
)
@projects
=
@projects
.
tagged_with
(
params
[
:label
])
if
params
[
:label
].
present?
@projects
=
@projects
.
page
(
params
[
:page
]).
per
(
30
)
end
# Get authored or assigned open merge requests
...
...
app/controllers/graphs_controller.rb
View file @
30d2d238
...
...
@@ -10,7 +10,7 @@ class GraphsController < ProjectResourceController
format
.
js
do
@repo
=
@project
.
repository
@stats
=
Gitlab
::
Git
::
GitStats
.
new
(
@repo
.
raw
,
@repo
.
root_ref
)
@log
=
@stats
.
parsed_log
.
to_json
@log
=
@stats
.
parsed_log
.
to_json
rescue
[]
end
end
end
...
...
app/controllers/groups_controller.rb
View file @
30d2d238
class
GroupsController
<
ApplicationController
respond_to
:html
before_filter
:group
,
except:
[
:new
,
:create
]
before_filter
:group
,
except:
[
:new
,
:create
,
:people
]
# Authorize
before_filter
:authorize_read_group!
,
except:
[
:new
,
:create
]
...
...
@@ -63,19 +63,8 @@ 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
else
@team_member
=
UsersProject
.
new
end
end
def
team_members
@group
.
add_users_to_project_teams
(
params
[
:user_ids
].
split
(
','
),
params
[
:project_access
])
redirect_to
people_group_path
(
@group
),
notice:
'Users were successfully added.'
@members
=
group
.
users_groups
.
order
(
'group_access DESC'
)
@users_group
=
UsersGroup
.
new
end
def
edit
...
...
@@ -83,7 +72,7 @@ class GroupsController < ApplicationController
def
update
group_params
=
params
[
:group
].
dup
owner_id
=
group_params
.
delete
(
:owner_id
)
owner_id
=
group_params
.
delete
(
:owner_id
)
if
owner_id
@group
.
owner
=
User
.
find
(
owner_id
)
...
...
app/controllers/issues_controller.rb
View file @
30d2d238
...
...
@@ -23,7 +23,7 @@ class IssuesController < ProjectResourceController
assignee_id
,
milestone_id
=
params
[
:assignee_id
],
params
[
:milestone_id
]
@assignee
=
@project
.
users
.
find
(
assignee_id
)
if
assignee_id
.
present?
&&
!
assignee_id
.
to_i
.
zero?
@assignee
=
@project
.
team
.
find
(
assignee_id
)
if
assignee_id
.
present?
&&
!
assignee_id
.
to_i
.
zero?
@milestone
=
@project
.
milestones
.
find
(
milestone_id
)
if
milestone_id
.
present?
&&
!
milestone_id
.
to_i
.
zero?
respond_to
do
|
format
|
...
...
app/controllers/team_members_controller.rb
View file @
30d2d238
...
...
@@ -4,10 +4,8 @@ class TeamMembersController < ProjectResourceController
before_filter
:authorize_admin_project!
,
except:
[
:index
,
:show
]
def
index
@team
=
@project
.
users_projects
.
scoped
@team
=
@team
.
send
(
params
[
:type
])
if
%w(masters developers reporters guests)
.
include?
(
params
[
:type
])
@team
=
@team
.
sort_by
(
&
:project_access
).
reverse
.
group_by
(
&
:project_access
)
@group
=
@project
.
group
@users_projects
=
@project
.
users_projects
.
order
(
'project_access DESC'
)
@assigned_teams
=
@project
.
user_team_project_relationships
end
...
...
app/controllers/users_controller.rb
View file @
30d2d238
...
...
@@ -3,7 +3,7 @@ class UsersController < ApplicationController
def
show
@user
=
User
.
find_by_username!
(
params
[
:username
])
@projects
=
@user
.
authorized_projects
.
where
(
'projects.id in (?)'
,
current_user
.
authorized_projects
.
map
(
&
:id
))
@projects
=
@user
.
authorized_projects
.
where
(
'projects.id in (?)'
,
current_user
.
authorized_projects
.
map
(
&
:id
))
.
order
(
'namespace_id DESC'
)
@events
=
@user
.
recent_events
.
where
(
project_id:
@projects
.
map
(
&
:id
)).
limit
(
20
)
@title
=
@user
.
name
...
...
app/controllers/users_groups_controller.rb
0 → 100644
View file @
30d2d238
class
UsersGroupsController
<
ApplicationController
before_filter
:group
# Authorize
before_filter
:authorize_admin_group!
layout
'group'
def
create
@group
.
add_users
(
params
[
:user_ids
].
split
(
','
),
params
[
:group_access
])
redirect_to
people_group_path
(
@group
),
notice:
'Users were successfully added.'
end
def
update
# TODO: implement
end
def
destroy
@users_group
=
@group
.
users_groups
.
find
(
params
[
:id
])
@users_group
.
destroy
respond_to
do
|
format
|
format
.
html
{
redirect_to
people_group_path
(
@group
),
notice:
'User was successfully removed from group.'
}
format
.
js
{
render
nothing:
true
}
end
end
protected
def
group
@group
||=
Group
.
find_by_path
(
params
[
:group_id
])
end
def
authorize_admin_group!
unless
can?
(
current_user
,
:manage_group
,
group
)
return
render_404
end
end
end
app/helpers/groups_helper.rb
View file @
30d2d238
...
...
@@ -14,4 +14,8 @@ module GroupsHelper
merge_requests_group_path
(
@group
,
options
)
end
end
def
remove_user_from_group_message
(
group
,
user
)
"You are going to remove
#{
user
.
name
}
from
#{
group
.
name
}
Group. Are you sure?"
end
end
app/models/ability.rb
View file @
30d2d238
...
...
@@ -50,6 +50,10 @@ class Ability
rules
<<
project_admin_rules
end
if
project
.
group
&&
project
.
group
.
owners
.
include?
(
user
)
rules
<<
project_admin_rules
end
rules
.
flatten
end
...
...
@@ -132,7 +136,7 @@ class Ability
rules
=
[]
# Only group owner and administrators can manage group
if
group
.
owner
==
user
||
user
.
admin?
if
group
.
owner
s
.
include?
(
user
)
||
user
.
admin?
rules
<<
[
:manage_group
,
:manage_namespace
...
...
app/models/group.rb
View file @
30d2d238
...
...
@@ -13,26 +13,28 @@
#
class
Group
<
Namespace
has_many
:users_groups
,
dependent: :destroy
has_many
:users
,
through: :users_groups
def
add_users_to_project_teams
(
user_ids
,
project_access
)
UsersProject
.
add_users_into_projects
(
projects
.
map
(
&
:id
),
user_ids
,
project_access
)
after_create
:add_owner
def
human_name
name
end
def
users
users
=
User
.
joins
(
:users_projects
).
where
(
users_projects:
{
project_id:
project_ids
})
users
=
users
<<
owner
users
.
uniq
def
owners
@owners
||=
(
users_groups
.
owners
.
map
(
&
:user
)
<<
owner
)
end
def
human_name
name
def
add_users
(
user_ids
,
group_access
)
user_ids
.
compact
.
each
do
|
user_id
|
self
.
users_groups
.
create
(
user_id:
user_id
,
group_access:
group_access
)
end
end
def
truncate_teams
UsersProject
.
truncate_teams
(
project_ids
)
private
def
add_owner
self
.
add_users
([
owner
.
id
],
UsersGroup
::
OWNER
)
end
end
app/models/project_team.rb
View file @
30d2d238
...
...
@@ -21,6 +21,16 @@ class ProjectTeam
end
end
def
find
user_id
user
=
project
.
users
.
find_by_id
(
user_id
)
if
group
user
||=
group
.
users
.
find_by_id
(
user_id
)
end
user
end
def
get_tm
user_id
project
.
users_projects
.
find_by_user_id
(
user_id
)
end
...
...
@@ -47,23 +57,23 @@ class ProjectTeam
end
def
members
project
.
users_project
s
fetch_member
s
end
def
guests
members
.
guests
.
map
(
&
:user
)
@guests
||=
fetch_members
(
:guests
)
end
def
reporters
members
.
reporters
.
map
(
&
:user
)
@reporters
||=
fetch_members
(
:reporters
)
end
def
developers
members
.
developers
.
map
(
&
:user
)
@developers
||=
fetch_members
(
:developers
)
end
def
masters
members
.
masters
.
map
(
&
:user
)
@masters
||=
fetch_members
(
:masters
)
end
def
import
(
source_project
)
...
...
@@ -96,4 +106,22 @@ class ProjectTeam
rescue
false
end
private
def
fetch_members
(
level
=
nil
)
project_members
=
project
.
users_projects
group_members
=
group
?
group
.
users_groups
:
[]
if
level
project_members
=
project_members
.
send
(
level
)
group_members
=
group_members
.
send
(
level
)
if
group
end
(
project_members
+
group_members
).
map
(
&
:user
).
uniq
end
def
group
project
.
group
end
end
app/models/user.rb
View file @
30d2d238
...
...
@@ -71,7 +71,9 @@ class User < ActiveRecord::Base
has_many
:keys
,
dependent: :destroy
# Groups
has_many
:groups
,
class_name:
"Group"
,
foreign_key: :owner_id
has_many
:own_groups
,
class_name:
"Group"
,
foreign_key: :owner_id
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
...
...
@@ -230,7 +232,7 @@ class User < ActiveRecord::Base
# Groups where user is an owner
def
owned_groups
groups
own_
groups
end
def
owned_teams
...
...
@@ -239,14 +241,14 @@ class User < ActiveRecord::Base
# Groups user has access to
def
authorized_groups
@group_ids
||=
(
groups
.
pluck
(
:id
)
+
authorized_projects
.
pluck
(
:namespace_id
))
@group_ids
||=
(
groups
.
pluck
(
:id
)
+
own_groups
.
pluck
(
:id
)
+
authorized_projects
.
pluck
(
:namespace_id
))
Group
.
where
(
id:
@group_ids
)
end
# Projects user has access to
def
authorized_projects
@project_ids
||=
(
owned_projects
.
pluck
(
:id
)
+
projects
.
pluck
(
:id
)).
uniq
@project_ids
||=
(
owned_projects
.
pluck
(
:id
)
+
groups
.
map
(
&
:projects
).
flatten
.
map
(
&
:id
)
+
projects
.
pluck
(
:id
)).
uniq
Project
.
where
(
id:
@project_ids
)
end
...
...
app/models/users_group.rb
0 → 100644
View file @
30d2d238
class
UsersGroup
<
ActiveRecord
::
Base
GUEST
=
10
REPORTER
=
20
DEVELOPER
=
30
MASTER
=
40
OWNER
=
50
def
self
.
group_access_roles
{
"Guest"
=>
GUEST
,
"Reporter"
=>
REPORTER
,
"Developer"
=>
DEVELOPER
,
"Master"
=>
MASTER
,
"Owner"
=>
OWNER
}
end
attr_accessible
:group_access
,
:user_id
belongs_to
:user
belongs_to
:group
scope
:guests
,
->
{
where
(
group_access:
GUEST
)
}
scope
:reporters
,
->
{
where
(
group_access:
REPORTER
)
}
scope
:developers
,
->
{
where
(
group_access:
DEVELOPER
)
}
scope
:masters
,
->
{
where
(
group_access:
MASTER
)
}
scope
:owners
,
->
{
where
(
group_access:
OWNER
)
}
scope
:with_group
,
->
(
group
)
{
where
(
group_id:
group
.
id
)
}
scope
:with_user
,
->
(
user
)
{
where
(
user_id:
user
.
id
)
}
validates
:group_access
,
inclusion:
{
in:
UsersGroup
.
group_access_roles
.
values
},
presence:
true
validates
:user_id
,
presence:
true
validates
:group_id
,
presence:
true
validates
:user_id
,
uniqueness:
{
scope:
[
:group_id
],
message:
"already exists in group"
}
delegate
:name
,
:username
,
:email
,
to: :user
,
prefix:
true
def
human_access
UsersGroup
.
group_access_roles
.
key
(
self
.
group_access
)
end
end
app/models/users_project.rb
View file @
30d2d238
...
...
@@ -129,9 +129,7 @@ class UsersProject < ActiveRecord::Base
Project
.
access_options
.
key
(
self
.
project_access
)
end
def
repo_access_human
self
.
class
.
access_roles
.
invert
[
self
.
project_access
]
end
alias_method
:human_access
,
:project_access_human
def
skip_git?
!!
@skip_git
...
...
app/services/system_hooks_service.rb
View file @
30d2d238
...
...
@@ -43,7 +43,7 @@ class SystemHooksService
project_id:
model
.
project_id
,
user_name:
model
.
user
.
name
,
user_email:
model
.
user
.
email
,
project_access:
model
.
repo
_access_human
project_access:
model
.
project
_access_human
})
end
end
...
...
app/views/admin/groups/show.html.haml
View file @
30d2d238
...
...
@@ -49,10 +49,23 @@
%strong
=
@group
.
created_at
.
stamp
(
"March 1, 1999"
)
.ui-box
%h5
.title
Projects
%small
(
#{
@group
.
projects
.
count
}
)
%ul
.well-list
-
@group
.
projects
.
sort_by
(
&
:name
).
each
do
|
project
|
%li
%strong
=
link_to
project
.
name_with_namespace
,
[
:admin
,
project
]
%span
.pull-right.light
%span
.monospace
=
project
.
path_with_namespace
+
".git"
.span6
.ui-box
%h5
.title
Add user
to Group projects
:
Add user
(s)
:
.ui-box-body.form-holder
%p
.light
Read more about project permissions
...
...
@@ -64,30 +77,18 @@
%div
.prepend-top-10
=
select_tag
:project_access
,
options_for_select
(
Project
.
access_options
),
{
class:
"project-access-select chosen span2"
}
%hr
=
submit_tag
'Add user
to projects in
group'
,
class:
"btn btn-create"
=
submit_tag
'Add user
s into
group'
,
class:
"btn btn-create"
.ui-box
%h5
.title
Users from
Group projects
Users from
#{
@group
.
name
}
Group
%small
(
#{
@group
.
users
.
count
}
)
(
#{
@group
.
users
_groups
.
count
}
)
%ul
.well-list
-
@group
.
users
.
sort_by
(
&
:name
).
each
do
|
user
|
-
@group
.
users_groups
.
order
(
'group_access DESC'
).
each
do
|
member
|
-
user
=
member
.
user
%li
{
class:
dom_class
(
user
)}
%strong
=
link_to
user
.
name
,
admin_user_path
(
user
)
%span
.pull-right.light
=
pluralize
user
.
authorized_projects
.
in_namespace
(
@group
).
count
,
'project'
=
member
.
human_access
.span6
.ui-box
%h5
.title
Projects
%small
(
#{
@group
.
projects
.
count
}
)
%ul
.well-list
-
@group
.
projects
.
sort_by
(
&
:name
).
each
do
|
project
|
%li
%strong
=
link_to
project
.
name_with_namespace
,
[
:admin
,
project
]
%span
.pull-right.light
%span
.monospace
=
project
.
path_with_namespace
+
".git"
app/views/groups/_new_group_member.html.haml
View file @
30d2d238
=
form_for
@
team_member
,
as: :team_member
,
url:
team_members_group
_path
(
@group
)
do
|
f
|
=
form_for
@
users_group
,
url:
group_users_groups
_path
(
@group
)
do
|
f
|
%fieldset
%legend
=
"New
Team member(s) for projects in
#{
@group
.
name
}
"
%legend
=
"New
Group member(s) for
#{
@group
.
name
}
"
%h6
1. Choose people you want in the
team
%h6
1. Choose people you want in the
group
.clearfix
=
f
.
label
:user_ids
,
"People"
.input
=
users_select_tag
(
:user_ids
,
multiple:
true
)
.input
=
users_select_tag
(
:user_ids
,
multiple:
true
,
class:
'input-large'
)
%h6
2. Set access level for them
.clearfix
=
f
.
label
:
project_access
,
"Project
Access"
.input
=
select_tag
:
project_access
,
options_for_select
(
Project
.
access_options
,
@team_member
.
project
_access
),
class:
"project-access-select chosen"
=
f
.
label
:
group_access
,
"Group
Access"
.input
=
select_tag
:
group_access
,
options_for_select
(
UsersGroup
.
group_access_roles
,
@users_group
.
group
_access
),
class:
"project-access-select chosen"
.form-actions
=
hidden_field_tag
:redirect_to
,
people_group_path
(
@group
)
=
f
.
submit
'Add
'
,
class:
"btn btn-sav
e"
=
f
.
submit
'Add
users into group'
,
class:
"btn btn-creat
e"
app/views/groups/_new_member.html.haml
deleted
100644 → 0
View file @
cc5440e8
=
form_for
@team_member
,
as: :team_member
,
url:
project_team_members_path
(
@project
,
@team_member
)
do
|
f
|
%fieldset
%legend
=
"New Team member(s) for
#{
@project
.
name
}
"
%h6
1. Choose people you want in the team
.clearfix
=
f
.
label
:user_ids
,
"People"
.input
=
users_select_tag
(
:user_ids
,
multiple:
true
)
%h6
2. Set access level for them
.clearfix
=
f
.
label
:project_access
,
"Project Access"
.input
=
select_tag
:project_access
,
options_for_select
(
Project
.
access_options
,
@team_member
.
project_access
),
class:
"project-access-select chosen"
.form-actions
=
hidden_field_tag
:redirect_to
,
people_group_path
(
@group
,
project_id:
@project
.
id
)
=
f
.
submit
'Add'
,
class:
"btn btn-save"
app/views/groups/_people_filter.html.haml
deleted
100644 → 0
View file @
cc5440e8
=
form_tag
people_group_path
(
@group
),
method:
'get'
do
%fieldset
%legend
Projects:
%ul
.nav.nav-pills.nav-stacked
-
@projects
.
each
do
|
project
|
%li
{
class:
(
"active"
if
params
[
:project_id
]
==
project
.
id
.
to_s
)}
=
link_to
people_group_path
(
@group
,
project_id:
project
.
id
)
do
=
project
.
name_with_namespace
%small
.pull-right
=
project
.
users
.
count
-
if
@projects
.
blank?
%p
.nothing_here_message
This group has no projects yet
%fieldset
%hr
=
link_to
"Reset"
,
people_group_path
(
@group
),
class:
'btn pull-right'
app/views/groups/people.html.haml
View file @
30d2d238
-
can_manage_group
=
current_user
.
can?
:manage_group
,
@group
.row
.span3
=
render
'people_filter'
.span9
-
if
can?
(
current_user
,
:manage_group
,
@group
)
=
render
(
@project
?
"new_member"
:
"new_group_member"
)
.span6
-
if
can_manage_group
=
render
"new_group_member"
-
else
.light-well
%h4
.nothing_here_message
Only group owners can manage group members
.span6
.ui-box
%h5
.title
Team
#{
@group
.
name
}
Group Members
%small
(
#{
@
users
.
size
}
)
(
#{
@
members
.
count
}
)
%ul
.well-list
-
@users
.
each
do
|
user
|
%li
=
image_tag
gravatar_icon
(
user
.
email
,
16
),
class:
"avatar s16"
%strong
=
user
.
name
%span
.cgray
=
user
.
email
-
if
@group
.
owner
==
user
%span
.btn.btn-small.disabled.pull-right
Group Owner
-
@members
.
each
do
|
member
|
=
render
'users_groups/users_group'
,
member:
member
,
show_controls:
can_manage_group
%p
.light
Group members get access to all projects in this group
app/views/issues/_form.html.haml
View file @
30d2d238
...
...
@@ -21,7 +21,7 @@
Assign to
.input
.pull-left
=
f
.
select
(
:assignee_id
,
@project
.
users
.
alphabetically
.
collect
{
|
p
|
[
p
.
name
,
p
.
id
]
},
{
include_blank:
"Select a user"
},
{
class:
'chosen'
})
=
f
.
select
(
:assignee_id
,
@project
.
team
.
members
.
sort_by
(
&
:name
).
map
{
|
p
|
[
p
.
name
,
p
.
id
]
},
{
include_blank:
"Select a user"
},
{
class:
'chosen'
})
.pull-right
=
link_to
'Assign to me'
,
'#'
,
class:
'btn btn-small assign-to-me-link'
...
...
app/views/issues/_issues.html.haml
View file @
30d2d238
...
...
@@ -7,7 +7,7 @@
%span
.update_issues_text
Update selected issues with
.left
=
select_tag
(
'update[status]'
,
options_for_select
([
'open'
,
'closed'
]),
prompt:
"Status"
)
=
select_tag
(
'update[assignee_id]'
,
options_from_collection_for_select
(
@project
.
users
.
all
,
"id"
,
"name"
,
params
[
:assignee_id
]),
prompt:
"Assignee"
)
=
select_tag
(
'update[assignee_id]'
,
options_from_collection_for_select
(
@project
.
team
.
members
,
"id"
,
"name"
,
params
[
:assignee_id
]),
prompt:
"Assignee"
)
=
select_tag
(
'update[milestone_id]'
,
options_from_collection_for_select
(
issues_active_milestones
,
"id"
,
"title"
,
params
[
:milestone_id
]),
prompt:
"Milestone"
)
=
hidden_field_tag
'update[issues_ids]'
,
[]
=
hidden_field_tag
:status
,
params
[
:status
]
...
...
@@ -50,7 +50,7 @@
Any
=
link_to
project_issues_with_filter_path
(
@project
,
assignee_id:
0
)
do
Unassigned
-
@project
.
us
ers
.
sort_by
(
&
:name
).
each
do
|
user
|
-
@project
.
team
.
memb
ers
.
sort_by
(
&
:name
).
each
do
|
user
|
%li
=
link_to
project_issues_with_filter_path
(
@project
,
assignee_id:
user
.
id
)
do
=
image_tag
gravatar_icon
(
user
.
email
),
class:
"avatar s16"
...
...
app/views/projects/_settings_nav.html.haml
View file @
30d2d238
...
...
@@ -6,7 +6,7 @@
=
nav_link
(
controller:
[
:team_members
,
:teams
])
do
=
link_to
project_team_index_path
(
@project
),
class:
"team-tab tab"
do
%i
.icon-group
Project
Members
Members
=
nav_link
(
controller: :deploy_keys
)
do
=
link_to
project_deploy_keys_path
(
@project
)
do
%span
...
...
app/views/team_members/_group_members.html.haml
0 → 100644
View file @
30d2d238
.ui-box
%h5
.title
%strong
#{
@group
.
name
}
Group
members (
#{
@group
.
users_groups
.
count
}
)
.pull-right
=
link_to
people_group_path
(
@group
),
class:
'btn btn-small'
do
%i
.icon-edit
%ul
.well-list
-
@group
.
users_groups
.
order
(
'group_access DESC'
).
each
do
|
member
|
=
render
'users_groups/users_group'
,
member:
member
,
show_controls:
false
app/views/team_members/_team.html.haml
View file @
30d2d238
-
can_admin_project
=
(
can?
current_user
,
:admin_project
,
@project
)
-
team
.
each
do
|
access
,
members
|
-
role
=
Project
.
access_options
.
key
(
access
).
pluralize
.ui-box
{
class:
role
.
downcase
}
.team-table
-
can_admin_project
=
(
can?
current_user
,
:admin_project
,
@project
)
.ui-box
%h5
.title
=
role
%span
.light
(
#{
members
.
size
}
)
%strong
#{
@project
.
name
}
Project
members (
#{
members
.
count
}
)
%ul
.well-list
-
members
.
sort_by
(
&
:user_name
).
each
do
|
team_member
|
-
members
.
each
do
|
team_member
|
=
render
'team_members/team_member'
,
member:
team_member
,
current_user_can_admin_project:
can_admin_project
app/views/team_members/_team_member.html.haml
View file @
30d2d238
-
user
=
member
.
user
-
allow_admin
=
current_user_can_admin_project
%li
{
id:
dom_id
(
user
),
class:
"team_member_row user_#{user.id}"
}
.row
.span4
=
link_to
user
,
title:
user
.
name
,
class:
"dark"
do
=
image_tag
gravatar_icon
(
user
.
email
,
32
),
class:
"avatar s32"
%strong
=
truncate
(
user
.
name
,
lenght:
40
)
%br
%small
.cgray
=
user
.
username
.span4.pull-right
.pull-right
-
if
allow_admin
.
left
.pull-
left
=
form_for
(
member
,
as: :team_member
,
url:
project_team_member_path
(
@project
,
member
.
user
))
do
|
f
|
=
f
.
select
:project_access
,
options_for_select
(
UsersProject
.
access_roles
,
member
.
project_access
),
{},
class:
"medium project-access-select span2 trigger-submit"
.pull-right
-
if
current_user
==
user
%span
.label.label-success
This is you!
-
if
@project
.
namespace_owner
==
user
%span
.label.label-info
Owner
-
elsif
user
.
blocked?
%span
.label.label-error
Blocked
-
elsif
allow_admin
=
link_to
project_team_member_path
(
@project
,
user
),
confirm:
remove_from_project_team_message
(
@project
,
user
),
method: :delete
,
class:
"btn-tiny btn btn-remove"
,
title:
'Remove user from team'
do
%i
.icon-minus.icon-white
=
image_tag
gravatar_icon
(
user
.
email
,
32
),
class:
"avatar s32"
%p
%strong
=
user
.
name
%span
.cgray
=
user
.
username
app/views/team_members/index.html.haml
View file @
30d2d238
=
render
"projects/settings_nav"
%h3
.page_title
Project Members
(
#{
@project
.
users
.
count
}
)
%small
Read more about project permissions
%strong
=
link_to
"here"
,
help_permissions_path
,
class:
"vlink"
Users with access to this project
-
if
can?
current_user
,
:admin_team_member
,
@project
%span
.pull-right
...
...
@@ -15,42 +11,25 @@
=
link_to
new_project_team_member_path
(
@project
),
class:
"btn btn-primary small grouped"
,
title:
"New Team Member"
do
New Team Member
%hr
%p
.light
Read more about project permissions
%strong
=
link_to
"here"
,
help_permissions_path
,
class:
"vlink"
.clearfix
.row
.span3
%ul
.nav.nav-pills.nav-stacked
%li
{
class:
(
"active"
if
!
params
[
:type
])}
=
link_to
project_team_index_path
(
type:
nil
)
do
All
%li
{
class:
(
"active"
if
params
[
:type
]
==
'masters'
)}
=
link_to
project_team_index_path
(
type:
'masters'
)
do
Masters
%span
.pull-right
=
@project
.
users_projects
.
masters
.
count
%li
{
class:
(
"active"
if
params
[
:type
]
==
'developers'
)}
=
link_to
project_team_index_path
(
type:
'developers'
)
do
Developers
%span
.pull-right
=
@project
.
users_projects
.
developers
.
count
%li
{
class:
(
"active"
if
params
[
:type
]
==
'reporters'
)}
=
link_to
project_team_index_path
(
type:
'reporters'
)
do
Reporters
%span
.pull-right
=
@project
.
users_projects
.
reporters
.
count
%li
{
class:
(
"active"
if
params
[
:type
]
==
'guests'
)}
=
link_to
project_team_index_path
(
type:
'guests'
)
do
Guests
%span
.pull-right
=
@project
.
users_projects
.
guests
.
count
-
if
@assigned_teams
.
present?
-
if
@group
.row
.span6
=
render
"team_members/group_members"
.span6
=
render
"team_members/team"
,
members:
@users_projects
-
else
=
render
"team_members/team"
,
members:
@users_projects
-
if
@assigned_teams
.
present?
%h5
Assigned teams
(
#{
@project
.
user_teams
.
count
}
)
%div
=
render
"team_members/assigned_teams"
,
assigned_teams:
@assigned_teams
.span9
%div
.team-table
=
render
"team_members/team"
,
team:
@team
app/views/users_groups/_users_group.html.haml
0 → 100644
View file @
30d2d238
-
user
=
member
.
user
-
return
unless
user
%li
{
class:
dom_class
(
member
)}
=
image_tag
gravatar_icon
(
user
.
email
,
16
),
class:
"avatar s16"
%strong
=
user
.
name
%span
.cgray
=
user
.
username
%span
.pull-right
-
if
@group
.
owners
.
include?
(
user
)
%span
.label.label-info
Group Owner
-
else
=
member
.
human_access
-
if
show_controls
&&
user
!=
current_user
=
link_to
group_users_group_path
(
@group
,
member
),
confirm:
remove_user_from_group_message
(
@group
,
user
),
method: :delete
,
remote:
true
,
class:
"btn-tiny btn btn-remove"
,
title:
'Remove user from group'
do
%i
.icon-minus.icon-white
config/routes.rb
View file @
30d2d238
...
...
@@ -149,10 +149,10 @@ Gitlab::Application.routes.draw do
member
do
get
:issues
get
:merge_requests
get
:search
get
:people
post
:team_members
end
resources
:users_groups
,
only:
[
:create
,
:update
,
:destroy
]
end
#
...
...
db/migrate/20130617095603_create_users_groups.rb
0 → 100644
View file @
30d2d238
class
CreateUsersGroups
<
ActiveRecord
::
Migration
def
change
create_table
:users_groups
do
|
t
|
t
.
integer
:group_access
,
null:
false
t
.
integer
:group_id
,
null:
false
t
.
integer
:user_id
,
null:
false
t
.
timestamps
end
end
end
db/schema.rb
View file @
30d2d238
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
:version
=>
2013061
4132337
)
do
ActiveRecord
::
Schema
.
define
(
:version
=>
2013061
7095603
)
do
create_table
"deploy_keys_projects"
,
:force
=>
true
do
|
t
|
t
.
integer
"deploy_key_id"
,
:null
=>
false
...
...
@@ -53,8 +53,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
t
.
integer
"assignee_id"
t
.
integer
"author_id"
t
.
integer
"project_id"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
integer
"position"
,
:default
=>
0
t
.
string
"branch_name"
t
.
text
"description"
...
...
@@ -71,8 +71,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
create_table
"keys"
,
:force
=>
true
do
|
t
|
t
.
integer
"user_id"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
text
"key"
t
.
string
"title"
t
.
string
"identifier"
...
...
@@ -89,8 +89,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
t
.
integer
"author_id"
t
.
integer
"assignee_id"
t
.
string
"title"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
text
"st_commits"
,
:limit
=>
2147483647
t
.
text
"st_diffs"
,
:limit
=>
2147483647
t
.
integer
"milestone_id"
...
...
@@ -139,8 +139,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
t
.
text
"note"
t
.
string
"noteable_type"
t
.
integer
"author_id"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
integer
"project_id"
t
.
string
"attachment"
t
.
string
"line_code"
...
...
@@ -158,8 +158,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
t
.
string
"name"
t
.
string
"path"
t
.
text
"description"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
integer
"creator_id"
t
.
string
"default_branch"
t
.
boolean
"issues_enabled"
,
:default
=>
true
,
:null
=>
false
...
...
@@ -206,8 +206,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
t
.
text
"content"
t
.
integer
"author_id"
,
:null
=>
false
t
.
integer
"project_id"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
string
"file_name"
t
.
datetime
"expires_at"
t
.
boolean
"private"
,
:default
=>
true
,
:null
=>
false
...
...
@@ -228,9 +228,6 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
t
.
datetime
"created_at"
end
add_index
"taggings"
,
[
"tag_id"
],
:name
=>
"index_taggings_on_tag_id"
add_index
"taggings"
,
[
"taggable_id"
,
"taggable_type"
,
"context"
],
:name
=>
"index_taggings_on_taggable_id_and_taggable_type_and_context"
create_table
"tags"
,
:force
=>
true
do
|
t
|
t
.
string
"name"
end
...
...
@@ -263,7 +260,7 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
create_table
"users"
,
:force
=>
true
do
|
t
|
t
.
string
"email"
,
:default
=>
""
,
:null
=>
false
t
.
string
"encrypted_password"
,
:default
=>
""
,
:null
=>
false
t
.
string
"encrypted_password"
,
:
limit
=>
128
,
:
default
=>
""
,
:null
=>
false
t
.
string
"reset_password_token"
t
.
datetime
"reset_password_sent_at"
t
.
datetime
"remember_created_at"
...
...
@@ -272,8 +269,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
t
.
datetime
"last_sign_in_at"
t
.
string
"current_sign_in_ip"
t
.
string
"last_sign_in_ip"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
string
"name"
t
.
boolean
"admin"
,
:default
=>
false
,
:null
=>
false
t
.
integer
"projects_limit"
,
:default
=>
10
...
...
@@ -299,16 +296,23 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
add_index
"users"
,
[
"admin"
],
:name
=>
"index_users_on_admin"
add_index
"users"
,
[
"email"
],
:name
=>
"index_users_on_email"
,
:unique
=>
true
add_index
"users"
,
[
"extern_uid"
,
"provider"
],
:name
=>
"index_users_on_extern_uid_and_provider"
,
:unique
=>
true
add_index
"users"
,
[
"name"
],
:name
=>
"index_users_on_name"
add_index
"users"
,
[
"reset_password_token"
],
:name
=>
"index_users_on_reset_password_token"
,
:unique
=>
true
add_index
"users"
,
[
"username"
],
:name
=>
"index_users_on_username"
create_table
"users_projects"
,
:force
=>
true
do
|
t
|
create_table
"users_groups"
,
:force
=>
true
do
|
t
|
t
.
integer
"group_access"
,
:null
=>
false
t
.
integer
"group_id"
,
:null
=>
false
t
.
integer
"user_id"
,
:null
=>
false
t
.
integer
"project_id"
,
:null
=>
false
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
end
create_table
"users_projects"
,
:force
=>
true
do
|
t
|
t
.
integer
"user_id"
,
:null
=>
false
t
.
integer
"project_id"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
integer
"project_access"
,
:default
=>
0
,
:null
=>
false
t
.
integer
"notification_level"
,
:default
=>
3
,
:null
=>
false
end
...
...
@@ -320,8 +324,8 @@ ActiveRecord::Schema.define(:version => 20130614132337) do
create_table
"web_hooks"
,
:force
=>
true
do
|
t
|
t
.
string
"url"
t
.
integer
"project_id"
t
.
datetime
"created_at"
,
:null
=>
false
t
.
datetime
"updated_at"
,
:null
=>
false
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
string
"type"
,
:default
=>
"ProjectHook"
t
.
integer
"service_id"
end
...
...
features/steps/admin/admin_groups.rb
View file @
30d2d238
...
...
@@ -45,7 +45,7 @@ class AdminGroups < Spinach::FeatureSteps
within
"#new_team_member"
do
select
"Reporter"
,
from:
"project_access"
end
click_button
"Add user
to projects in
group"
click_button
"Add user
s into
group"
end
Then
'I should see "John" in team list in every project as "Reporter"'
do
...
...
features/steps/group/group.rb
View file @
30d2d238
...
...
@@ -39,11 +39,11 @@ class Groups < Spinach::FeatureSteps
And
'I select user "John" from list with role "Reporter"'
do
user
=
User
.
find_by_name
(
"John"
)
within
"
#new_team_member
"
do
within
"
.new_users_group
"
do
select2
(
user
.
id
,
from:
"#user_ids"
,
multiple:
true
)
select
"Reporter"
,
from:
"
project
_access"
select
"Reporter"
,
from:
"
group
_access"
end
click_button
"Add"
click_button
"Add
users into group
"
end
Then
'I should see user "John" in team list'
do
...
...
features/steps/project/project_active_tab.rb
View file @
30d2d238
...
...
@@ -45,7 +45,7 @@ class ProjectActiveTab < Spinach::FeatureSteps
# Sub Tabs: Home
Given
'I click the "Team" tab'
do
click_link
(
'
Project
Members'
)
click_link
(
'Members'
)
end
Given
'I click the "Attachments" tab'
do
...
...
@@ -73,7 +73,7 @@ class ProjectActiveTab < Spinach::FeatureSteps
end
Then
'the active sub tab should be Team'
do
ensure_active_sub_tab
(
'
Project
Members'
)
ensure_active_sub_tab
(
'Members'
)
end
Then
'the active sub tab should be Attachments'
do
...
...
features/steps/project/project_team_management.rb
View file @
30d2d238
...
...
@@ -30,14 +30,20 @@ class ProjectTeamManagement < Spinach::FeatureSteps
end
Then
'I should see "Mike" in team list as "Reporter"'
do
within
'.reporters'
do
user
=
User
.
find_by_name
(
"Mike"
)
within
"#user_
#{
user
.
id
}
"
do
page
.
should
have_content
(
'Mike'
)
page
.
find
(
'#team_member_project_access'
).
value
.
should
==
access_value
(
:reporter
)
end
end
Given
'I should see "Sam" in team list as "Developer"'
do
within
'.developers'
do
user
=
User
.
find_by_name
(
"Sam"
)
within
"#user_
#{
user
.
id
}
"
do
page
.
should
have_content
(
'Sam'
)
page
.
find
(
'#team_member_project_access'
).
value
.
should
==
access_value
(
:developer
)
end
end
...
...
@@ -49,8 +55,10 @@ class ProjectTeamManagement < Spinach::FeatureSteps
end
And
'I should see "Sam" in team list as "Reporter"'
do
within
'.reporters'
do
user
=
User
.
find_by_name
(
"Sam"
)
within
".user_
#{
user
.
id
}
"
do
page
.
should
have_content
(
'Sam'
)
page
.
find
(
'#team_member_project_access'
).
value
.
should
==
access_value
(
:reporter
)
end
end
...
...
@@ -103,4 +111,10 @@ class ProjectTeamManagement < Spinach::FeatureSteps
click_link
(
'Remove user from team'
)
end
end
private
def
access_value
(
key
)
UsersProject
.
roles_hash
[
key
].
to_s
end
end
spec/factories/users_groups.rb
0 → 100644
View file @
30d2d238
FactoryGirl
.
define
do
factory
:users_group
do
group_access
{
UsersGroup
::
OWNER
}
group
user
end
end
spec/models/users_group_spec.rb
0 → 100644
View file @
30d2d238
require
'spec_helper'
describe
UsersGroup
do
describe
"Associations"
do
it
{
should
belong_to
(
:group
)
}
it
{
should
belong_to
(
:user
)
}
end
describe
"Mass assignment"
do
it
{
should_not
allow_mass_assignment_of
(
:group_id
)
}
end
describe
"Validation"
do
let!
(
:users_group
)
{
create
(
:users_group
)
}
it
{
should
validate_presence_of
(
:user_id
)
}
it
{
should
validate_uniqueness_of
(
:user_id
).
scoped_to
(
:group_id
).
with_message
(
/already exists/
)
}
it
{
should
validate_presence_of
(
:group_id
)
}
it
{
should
ensure_inclusion_of
(
:group_access
).
in_array
(
UsersGroup
.
group_access_roles
.
values
)
}
end
describe
"Delegate methods"
do
it
{
should
respond_to
(
:user_name
)
}
it
{
should
respond_to
(
:user_email
)
}
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment