Skip to content
Snippets Groups Projects
Commit 396f85e4 authored by Sean McGivern's avatar Sean McGivern
Browse files

Add expiration date to group memberships

parent 8b165628
No related branches found
No related tags found
No related merge requests found
Showing with 58 additions and 34 deletions
Loading
Loading
@@ -126,6 +126,7 @@
new NotificationsDropdown();
break;
case 'groups:group_members:index':
new MemberExpirationDate();
new GroupMembers();
new UsersSelect();
break;
Loading
Loading
Loading
Loading
@@ -21,7 +21,12 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
 
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.'
end
Loading
Loading
@@ -63,7 +68,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
protected
 
def member_params
params.require(:group_member).permit(:access_level, :user_id)
params.require(:group_member).permit(:access_level, :user_id, :expires_at)
end
 
# MembershipActions concern
Loading
Loading
Loading
Loading
@@ -95,34 +95,40 @@ class Group < Namespace
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|
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
 
def add_user(user, access_level, current_user = nil)
add_users([user], access_level, current_user)
def add_user(user, access_level, current_user: nil, expires_at: nil)
add_users([user], access_level, current_user: current_user, expires_at: expires_at)
end
 
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
 
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
 
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
 
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
 
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
 
def has_owner?(user)
Loading
Loading
Loading
Loading
@@ -1003,8 +1003,8 @@ class Project < ActiveRecord::Base
project_members.find_by(user_id: user)
end
 
def add_user(user, access_level, current_user = nil)
team.add_user(user, access_level, current_user)
def add_user(user, access_level, current_user: nil, expires_at: nil)
team.add_user(user, access_level, current_user: current_user, expires_at: expires_at)
end
 
def default_branch
Loading
Loading
Loading
Loading
@@ -17,7 +17,7 @@ class ProjectTeam
if users.respond_to?(:each)
add_users(users, access, current_user: current_user)
else
add_user(users, access, current_user)
add_user(users, access, current_user: current_user)
end
end
 
Loading
Loading
@@ -43,8 +43,8 @@ class ProjectTeam
)
end
 
def add_user(user, access, current_user = nil)
add_users([user], access, current_user: current_user)
def add_user(user, access, current_user: nil, expires_at: nil)
add_users([user], access, current_user: current_user, expires_at: expires_at)
end
 
# Remove all users from project team
Loading
Loading
Loading
Loading
@@ -14,5 +14,12 @@
Read more about role permissions
%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
= f.submit 'Add users to group', class: "btn btn-create"
:plain
$("##{dom_id(@group_member)}").replaceWith('#{escape_javascript(render('shared/members/member', member: @group_member))}');
new MemberExpirationDate();
Loading
Loading
@@ -82,12 +82,11 @@
= label_tag "member_access_level_#{member.id}", 'Project access', class: 'control-label'
.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}"
- if member.is_a?(ProjectMember)
.form-group
= label_tag "member_expires_at_#{member.id}", 'Access expiration date', class: 'control-label'
.col-sm-10
.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}"
%i.clear-icon.js-clear-input
.form-group
= label_tag "member_expires_at_#{member.id}", 'Access expiration date', class: 'control-label'
.col-sm-10
.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}"
%i.clear-icon.js-clear-input
.prepend-top-10
= f.submit 'Save', class: 'btn btn-save btn-sm'
Loading
Loading
@@ -117,7 +117,7 @@ class Spinach::Features::GroupMembers < Spinach::FeatureSteps
 
page.within "#group_member_#{member.id}" do
click_button 'Edit'
select 'Developer', from: 'group_member_access_level'
select 'Developer', from: "member_access_level_#{member.id}"
click_on 'Save'
end
end
Loading
Loading
Loading
Loading
@@ -66,7 +66,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps
project_member = project.project_members.find_by(user_id: user.id)
page.within "#project_member_#{project_member.id}" do
click_button 'Edit'
select "Reporter", from: "project_member_access_level"
select "Reporter", from: "member_access_level_#{project_member.id}"
click_button "Save"
end
end
Loading
Loading
Loading
Loading
@@ -97,6 +97,10 @@ module API
member = options[:member] || options[:members].find { |m| m.user_id == user.id }
member.access_level
end
expose :expires_at do |user, options|
member = options[:member] || options[:members].find { |m| m.user_id == user.id }
member.expires_at
end
end
 
class AccessRequester < UserBasic
Loading
Loading
@@ -104,9 +108,6 @@ module API
access_requester = options[:access_requester] || options[:access_requesters].find { |m| m.user_id == user.id }
access_requester.requested_at
end
expose :expires_at do |user, options|
options[:project].project_members.find_by(user_id: user.id).expires_at
end
end
 
class Group < Grape::Entity
Loading
Loading
Loading
Loading
@@ -49,6 +49,7 @@ module API
# id (required) - The group/project ID
# user_id (required) - The user ID of the new member
# access_level (required) - A valid access level
# expires_at (optional) - Date string in the format YEAR-MONTH-DAY
#
# Example Request:
# POST /groups/:id/members
Loading
Loading
@@ -72,7 +73,7 @@ module API
conflict!('Member already exists') if source_type == 'group' && 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])
end
 
Loading
Loading
@@ -81,7 +82,7 @@ module API
else
# 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.
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
 
# This is to ensure back-compatibility but 400 behavior should be used
Loading
Loading
@@ -97,6 +98,7 @@ module API
# id (required) - The group/project ID
# user_id (required) - The user ID of the member
# access_level (required) - A valid access level
# expires_at (optional) - Date string in the format YEAR-MONTH-DAY
#
# Example Request:
# PUT /groups/:id/members/:user_id
Loading
Loading
@@ -107,7 +109,7 @@ module API
required_attributes! [:user_id, :access_level]
 
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)
present member.user, with: Entities::Member, member: member
Loading
Loading
Loading
Loading
@@ -19,7 +19,7 @@ feature 'Projects > Members > Master adds member with expiration date', feature:
 
page.within '.users-project-form' do
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'
end
 
Loading
Loading
Loading
Loading
@@ -122,12 +122,13 @@ describe API::Members, api: true do
it 'creates a new member' do
expect do
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)
end.to change { source.members.count }.by(1)
expect(json_response['id']).to eq(stranger.id)
expect(json_response['access_level']).to eq(Member::DEVELOPER)
expect(json_response['expires_at']).to eq('2016-08-05')
end
end
 
Loading
Loading
@@ -183,11 +184,12 @@ describe API::Members, api: true do
context 'when authenticated as a master/owner' do
it 'updates the member' do
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(json_response['id']).to eq(developer.id)
expect(json_response['access_level']).to eq(Member::MASTER)
expect(json_response['expires_at']).to eq('2016-08-05')
end
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment