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
Tatuya Kamada
gitlab-ce
Commits
396f85e4
Commit
396f85e4
authored
Aug 18, 2016
by
Sean McGivern
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add expiration date to group memberships
parent
8b165628
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
58 additions
and
34 deletions
+58
-34
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+1
-0
app/controllers/groups/group_members_controller.rb
app/controllers/groups/group_members_controller.rb
+7
-2
app/models/group.rb
app/models/group.rb
+15
-9
app/models/project.rb
app/models/project.rb
+2
-2
app/models/project_team.rb
app/models/project_team.rb
+3
-3
app/views/groups/group_members/_new_group_member.html.haml
app/views/groups/group_members/_new_group_member.html.haml
+7
-0
app/views/groups/group_members/update.js.haml
app/views/groups/group_members/update.js.haml
+1
-0
app/views/shared/members/_member.html.haml
app/views/shared/members/_member.html.haml
+6
-7
features/steps/group/members.rb
features/steps/group/members.rb
+1
-1
features/steps/project/team_management.rb
features/steps/project/team_management.rb
+1
-1
lib/api/entities.rb
lib/api/entities.rb
+4
-3
lib/api/members.rb
lib/api/members.rb
+5
-3
spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
...s/members/master_adds_member_with_expiration_date_spec.rb
+1
-1
spec/requests/api/members_spec.rb
spec/requests/api/members_spec.rb
+4
-2
No files found.
app/assets/javascripts/dispatcher.js
View file @
396f85e4
...
@@ -126,6 +126,7 @@
...
@@ -126,6 +126,7 @@
new
NotificationsDropdown
();
new
NotificationsDropdown
();
break
;
break
;
case
'
groups:group_members:index
'
:
case
'
groups:group_members:index
'
:
new
MemberExpirationDate
();
new
GroupMembers
();
new
GroupMembers
();
new
UsersSelect
();
new
UsersSelect
();
break
;
break
;
...
...
app/controllers/groups/group_members_controller.rb
View file @
396f85e4
...
@@ -21,7 +21,12 @@ class Groups::GroupMembersController < Groups::ApplicationController
...
@@ -21,7 +21,12 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
end
def
create
def
create
@group
.
add_users
(
params
[
:user_ids
].
split
(
','
),
params
[
:access_level
],
current_user
)
@group
.
add_users
(
params
[
:user_ids
].
split
(
','
),
params
[
:access_level
],
current_user:
current_user
,
expires_at:
params
[
:expires_at
]
)
redirect_to
group_group_members_path
(
@group
),
notice:
'Users were successfully added.'
redirect_to
group_group_members_path
(
@group
),
notice:
'Users were successfully added.'
end
end
...
@@ -63,7 +68,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
...
@@ -63,7 +68,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
protected
protected
def
member_params
def
member_params
params
.
require
(
:group_member
).
permit
(
:access_level
,
:user_id
)
params
.
require
(
:group_member
).
permit
(
:access_level
,
:user_id
,
:expires_at
)
end
end
# MembershipActions concern
# MembershipActions concern
...
...
app/models/group.rb
View file @
396f85e4
...
@@ -95,34 +95,40 @@ class Group < Namespace
...
@@ -95,34 +95,40 @@ class Group < Namespace
end
end
end
end
def
add_users
(
user_ids
,
access_level
,
current_user
=
nil
)
def
add_users
(
user_ids
,
access_level
,
current_user
:
nil
,
expires_at:
nil
)
user_ids
.
each
do
|
user_id
|
user_ids
.
each
do
|
user_id
|
Member
.
add_user
(
self
.
group_members
,
user_id
,
access_level
,
current_user:
current_user
)
Member
.
add_user
(
self
.
group_members
,
user_id
,
access_level
,
current_user:
current_user
,
expires_at:
expires_at
)
end
end
end
end
def
add_user
(
user
,
access_level
,
current_user
=
nil
)
def
add_user
(
user
,
access_level
,
current_user
:
nil
,
expires_at:
nil
)
add_users
([
user
],
access_level
,
current_user
)
add_users
([
user
],
access_level
,
current_user
:
current_user
,
expires_at:
expires_at
)
end
end
def
add_guest
(
user
,
current_user
=
nil
)
def
add_guest
(
user
,
current_user
=
nil
)
add_user
(
user
,
Gitlab
::
Access
::
GUEST
,
current_user
)
add_user
(
user
,
Gitlab
::
Access
::
GUEST
,
current_user
:
current_user
)
end
end
def
add_reporter
(
user
,
current_user
=
nil
)
def
add_reporter
(
user
,
current_user
=
nil
)
add_user
(
user
,
Gitlab
::
Access
::
REPORTER
,
current_user
)
add_user
(
user
,
Gitlab
::
Access
::
REPORTER
,
current_user
:
current_user
)
end
end
def
add_developer
(
user
,
current_user
=
nil
)
def
add_developer
(
user
,
current_user
=
nil
)
add_user
(
user
,
Gitlab
::
Access
::
DEVELOPER
,
current_user
)
add_user
(
user
,
Gitlab
::
Access
::
DEVELOPER
,
current_user
:
current_user
)
end
end
def
add_master
(
user
,
current_user
=
nil
)
def
add_master
(
user
,
current_user
=
nil
)
add_user
(
user
,
Gitlab
::
Access
::
MASTER
,
current_user
)
add_user
(
user
,
Gitlab
::
Access
::
MASTER
,
current_user
:
current_user
)
end
end
def
add_owner
(
user
,
current_user
=
nil
)
def
add_owner
(
user
,
current_user
=
nil
)
add_user
(
user
,
Gitlab
::
Access
::
OWNER
,
current_user
)
add_user
(
user
,
Gitlab
::
Access
::
OWNER
,
current_user
:
current_user
)
end
end
def
has_owner?
(
user
)
def
has_owner?
(
user
)
...
...
app/models/project.rb
View file @
396f85e4
...
@@ -1003,8 +1003,8 @@ class Project < ActiveRecord::Base
...
@@ -1003,8 +1003,8 @@ class Project < ActiveRecord::Base
project_members
.
find_by
(
user_id:
user
)
project_members
.
find_by
(
user_id:
user
)
end
end
def
add_user
(
user
,
access_level
,
current_user
=
nil
)
def
add_user
(
user
,
access_level
,
current_user
:
nil
,
expires_at:
nil
)
team
.
add_user
(
user
,
access_level
,
current_user
)
team
.
add_user
(
user
,
access_level
,
current_user
:
current_user
,
expires_at:
expires_at
)
end
end
def
default_branch
def
default_branch
...
...
app/models/project_team.rb
View file @
396f85e4
...
@@ -17,7 +17,7 @@ class ProjectTeam
...
@@ -17,7 +17,7 @@ class ProjectTeam
if
users
.
respond_to?
(
:each
)
if
users
.
respond_to?
(
:each
)
add_users
(
users
,
access
,
current_user:
current_user
)
add_users
(
users
,
access
,
current_user:
current_user
)
else
else
add_user
(
users
,
access
,
current_user
)
add_user
(
users
,
access
,
current_user
:
current_user
)
end
end
end
end
...
@@ -43,8 +43,8 @@ class ProjectTeam
...
@@ -43,8 +43,8 @@ class ProjectTeam
)
)
end
end
def
add_user
(
user
,
access
,
current_user
=
nil
)
def
add_user
(
user
,
access
,
current_user
:
nil
,
expires_at:
nil
)
add_users
([
user
],
access
,
current_user:
current_user
)
add_users
([
user
],
access
,
current_user:
current_user
,
expires_at:
expires_at
)
end
end
# Remove all users from project team
# Remove all users from project team
...
...
app/views/groups/group_members/_new_group_member.html.haml
View file @
396f85e4
...
@@ -14,5 +14,12 @@
...
@@ -14,5 +14,12 @@
Read more about role permissions
Read more about role permissions
%strong
=
link_to
"here"
,
help_page_path
(
"user/permissions"
),
class:
"vlink"
%strong
=
link_to
"here"
,
help_page_path
(
"user/permissions"
),
class:
"vlink"
.form-group
=
f
.
label
:expires_at
,
'Access expiration date'
,
class:
'control-label'
.col-sm-10
.clearable-input
=
text_field_tag
:expires_at
,
nil
,
class:
'form-control js-access-expiration-date'
,
placeholder:
'Select access expiration date'
%i
.clear-icon.js-clear-input
.form-actions
.form-actions
=
f
.
submit
'Add users to group'
,
class:
"btn btn-create"
=
f
.
submit
'Add users to group'
,
class:
"btn btn-create"
app/views/groups/group_members/update.js.haml
View file @
396f85e4
:plain
:plain
$("##{dom_id(@group_member)}").replaceWith('
#{
escape_javascript
(
render
(
'shared/members/member'
,
member:
@group_member
))
}
');
$("##{dom_id(@group_member)}").replaceWith('
#{
escape_javascript
(
render
(
'shared/members/member'
,
member:
@group_member
))
}
');
new MemberExpirationDate();
app/views/shared/members/_member.html.haml
View file @
396f85e4
...
@@ -82,12 +82,11 @@
...
@@ -82,12 +82,11 @@
=
label_tag
"member_access_level_
#{
member
.
id
}
"
,
'Project access'
,
class:
'control-label'
=
label_tag
"member_access_level_
#{
member
.
id
}
"
,
'Project access'
,
class:
'control-label'
.col-sm-10
.col-sm-10
=
f
.
select
:access_level
,
options_for_select
(
member
.
class
.
access_level_roles
,
member
.
access_level
),
{},
class:
'form-control'
,
id:
"member_access_level_
#{
member
.
id
}
"
=
f
.
select
:access_level
,
options_for_select
(
member
.
class
.
access_level_roles
,
member
.
access_level
),
{},
class:
'form-control'
,
id:
"member_access_level_
#{
member
.
id
}
"
-
if
member
.
is_a?
(
ProjectMember
)
.form-group
.form-group
=
label_tag
"member_expires_at_
#{
member
.
id
}
"
,
'Access expiration date'
,
class:
'control-label'
=
label_tag
"member_expires_at_
#{
member
.
id
}
"
,
'Access expiration date'
,
class:
'control-label'
.col-sm-10
.col-sm-10
.clearable-input
.clearable-input
=
f
.
text_field
:expires_at
,
class:
'form-control js-access-expiration-date'
,
placeholder:
'Select access expiration date'
,
id:
"member_expires_at_
#{
member
.
id
}
"
=
f
.
text_field
:expires_at
,
class:
'form-control js-access-expiration-date'
,
placeholder:
'Select access expiration date'
,
id:
"member_expires_at_
#{
member
.
id
}
"
%i
.clear-icon.js-clear-input
%i
.clear-icon.js-clear-input
.prepend-top-10
.prepend-top-10
=
f
.
submit
'Save'
,
class:
'btn btn-save btn-sm'
=
f
.
submit
'Save'
,
class:
'btn btn-save btn-sm'
features/steps/group/members.rb
View file @
396f85e4
...
@@ -117,7 +117,7 @@ class Spinach::Features::GroupMembers < Spinach::FeatureSteps
...
@@ -117,7 +117,7 @@ class Spinach::Features::GroupMembers < Spinach::FeatureSteps
page
.
within
"#group_member_
#{
member
.
id
}
"
do
page
.
within
"#group_member_
#{
member
.
id
}
"
do
click_button
'Edit'
click_button
'Edit'
select
'Developer'
,
from:
'group_member_access_level'
select
'Developer'
,
from:
"member_access_level_
#{
member
.
id
}
"
click_on
'Save'
click_on
'Save'
end
end
end
end
...
...
features/steps/project/team_management.rb
View file @
396f85e4
...
@@ -66,7 +66,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps
...
@@ -66,7 +66,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps
project_member
=
project
.
project_members
.
find_by
(
user_id:
user
.
id
)
project_member
=
project
.
project_members
.
find_by
(
user_id:
user
.
id
)
page
.
within
"#project_member_
#{
project_member
.
id
}
"
do
page
.
within
"#project_member_
#{
project_member
.
id
}
"
do
click_button
'Edit'
click_button
'Edit'
select
"Reporter"
,
from:
"
project_member_access_level
"
select
"Reporter"
,
from:
"
member_access_level_
#{
project_member
.
id
}
"
click_button
"Save"
click_button
"Save"
end
end
end
end
...
...
lib/api/entities.rb
View file @
396f85e4
...
@@ -97,6 +97,10 @@ module API
...
@@ -97,6 +97,10 @@ module API
member
=
options
[
:member
]
||
options
[
:members
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
member
=
options
[
:member
]
||
options
[
:members
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
member
.
access_level
member
.
access_level
end
end
expose
:expires_at
do
|
user
,
options
|
member
=
options
[
:member
]
||
options
[
:members
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
member
.
expires_at
end
end
end
class
AccessRequester
<
UserBasic
class
AccessRequester
<
UserBasic
...
@@ -104,9 +108,6 @@ module API
...
@@ -104,9 +108,6 @@ module API
access_requester
=
options
[
:access_requester
]
||
options
[
:access_requesters
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
access_requester
=
options
[
:access_requester
]
||
options
[
:access_requesters
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
access_requester
.
requested_at
access_requester
.
requested_at
end
end
expose
:expires_at
do
|
user
,
options
|
options
[
:project
].
project_members
.
find_by
(
user_id:
user
.
id
).
expires_at
end
end
end
class
Group
<
Grape
::
Entity
class
Group
<
Grape
::
Entity
...
...
lib/api/members.rb
View file @
396f85e4
...
@@ -49,6 +49,7 @@ module API
...
@@ -49,6 +49,7 @@ module API
# id (required) - The group/project ID
# id (required) - The group/project ID
# user_id (required) - The user ID of the new member
# user_id (required) - The user ID of the new member
# access_level (required) - A valid access level
# access_level (required) - A valid access level
# expires_at (optional) - Date string in the format YEAR-MONTH-DAY
#
#
# Example Request:
# Example Request:
# POST /groups/:id/members
# POST /groups/:id/members
...
@@ -72,7 +73,7 @@ module API
...
@@ -72,7 +73,7 @@ module API
conflict!
(
'Member already exists'
)
if
source_type
==
'group'
&&
member
conflict!
(
'Member already exists'
)
if
source_type
==
'group'
&&
member
unless
member
unless
member
source
.
add_user
(
params
[
:user_id
],
params
[
:access_level
],
current_user
)
source
.
add_user
(
params
[
:user_id
],
params
[
:access_level
],
current_user
:
current_user
,
expires_at:
params
[
:expires_at
]
)
member
=
source
.
members
.
find_by
(
user_id:
params
[
:user_id
])
member
=
source
.
members
.
find_by
(
user_id:
params
[
:user_id
])
end
end
...
@@ -81,7 +82,7 @@ module API
...
@@ -81,7 +82,7 @@ module API
else
else
# Since `source.add_user` doesn't return a member object, we have to
# Since `source.add_user` doesn't return a member object, we have to
# build a new one and populate its errors in order to render them.
# build a new one and populate its errors in order to render them.
member
=
source
.
members
.
build
(
attributes_for_keys
([
:user_id
,
:access_level
]))
member
=
source
.
members
.
build
(
attributes_for_keys
([
:user_id
,
:access_level
,
:expires_at
]))
member
.
valid?
# populate the errors
member
.
valid?
# populate the errors
# This is to ensure back-compatibility but 400 behavior should be used
# This is to ensure back-compatibility but 400 behavior should be used
...
@@ -97,6 +98,7 @@ module API
...
@@ -97,6 +98,7 @@ module API
# id (required) - The group/project ID
# id (required) - The group/project ID
# user_id (required) - The user ID of the member
# user_id (required) - The user ID of the member
# access_level (required) - A valid access level
# access_level (required) - A valid access level
# expires_at (optional) - Date string in the format YEAR-MONTH-DAY
#
#
# Example Request:
# Example Request:
# PUT /groups/:id/members/:user_id
# PUT /groups/:id/members/:user_id
...
@@ -107,7 +109,7 @@ module API
...
@@ -107,7 +109,7 @@ module API
required_attributes!
[
:user_id
,
:access_level
]
required_attributes!
[
:user_id
,
:access_level
]
member
=
source
.
members
.
find_by!
(
user_id:
params
[
:user_id
])
member
=
source
.
members
.
find_by!
(
user_id:
params
[
:user_id
])
attrs
=
attributes_for_keys
[
:access_level
]
attrs
=
attributes_for_keys
[
:access_level
,
:expires_at
]
if
member
.
update_attributes
(
attrs
)
if
member
.
update_attributes
(
attrs
)
present
member
.
user
,
with:
Entities
::
Member
,
member:
member
present
member
.
user
,
with:
Entities
::
Member
,
member:
member
...
...
spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
View file @
396f85e4
...
@@ -19,7 +19,7 @@ feature 'Projects > Members > Master adds member with expiration date', feature:
...
@@ -19,7 +19,7 @@ feature 'Projects > Members > Master adds member with expiration date', feature:
page
.
within
'.users-project-form'
do
page
.
within
'.users-project-form'
do
select2
(
new_member
.
id
,
from:
'#user_ids'
,
multiple:
true
)
select2
(
new_member
.
id
,
from:
'#user_ids'
,
multiple:
true
)
fill_in
'
Access expiration date
'
,
with:
'2016-08-10'
fill_in
'
expires_at
'
,
with:
'2016-08-10'
click_on
'Add users to project'
click_on
'Add users to project'
end
end
...
...
spec/requests/api/members_spec.rb
View file @
396f85e4
...
@@ -122,12 +122,13 @@ describe API::Members, api: true do
...
@@ -122,12 +122,13 @@ describe API::Members, api: true do
it
'creates a new member'
do
it
'creates a new member'
do
expect
do
expect
do
post
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members"
,
master
),
post
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members"
,
master
),
user_id:
stranger
.
id
,
access_level:
Member
::
DEVELOPER
user_id:
stranger
.
id
,
access_level:
Member
::
DEVELOPER
,
expires_at:
'2016-08-05'
expect
(
response
).
to
have_http_status
(
201
)
expect
(
response
).
to
have_http_status
(
201
)
end
.
to
change
{
source
.
members
.
count
}.
by
(
1
)
end
.
to
change
{
source
.
members
.
count
}.
by
(
1
)
expect
(
json_response
[
'id'
]).
to
eq
(
stranger
.
id
)
expect
(
json_response
[
'id'
]).
to
eq
(
stranger
.
id
)
expect
(
json_response
[
'access_level'
]).
to
eq
(
Member
::
DEVELOPER
)
expect
(
json_response
[
'access_level'
]).
to
eq
(
Member
::
DEVELOPER
)
expect
(
json_response
[
'expires_at'
]).
to
eq
(
'2016-08-05'
)
end
end
end
end
...
@@ -183,11 +184,12 @@ describe API::Members, api: true do
...
@@ -183,11 +184,12 @@ describe API::Members, api: true do
context
'when authenticated as a master/owner'
do
context
'when authenticated as a master/owner'
do
it
'updates the member'
do
it
'updates the member'
do
put
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members/
#{
developer
.
id
}
"
,
master
),
put
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members/
#{
developer
.
id
}
"
,
master
),
access_level:
Member
::
MASTER
access_level:
Member
::
MASTER
,
expires_at:
'2016-08-05'
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'id'
]).
to
eq
(
developer
.
id
)
expect
(
json_response
[
'id'
]).
to
eq
(
developer
.
id
)
expect
(
json_response
[
'access_level'
]).
to
eq
(
Member
::
MASTER
)
expect
(
json_response
[
'access_level'
]).
to
eq
(
Member
::
MASTER
)
expect
(
json_response
[
'expires_at'
]).
to
eq
(
'2016-08-05'
)
end
end
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