Add expiration date to group memberships
This commit is contained in:
parent
8b1656282b
commit
396f85e438
|
@ -126,6 +126,7 @@
|
|||
new NotificationsDropdown();
|
||||
break;
|
||||
case 'groups:group_members:index':
|
||||
new MemberExpirationDate();
|
||||
new GroupMembers();
|
||||
new UsersSelect();
|
||||
break;
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
:plain
|
||||
$("##{dom_id(@group_member)}").replaceWith('#{escape_javascript(render('shared/members/member', member: @group_member))}');
|
||||
new MemberExpirationDate();
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -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…
Reference in New Issue