Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

suspend on org/users #1355

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/travis/api/v3/models/bulk_change_result.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Travis::API::V3
class Models::BulkChangeResult
attr_accessor :changed, :skipped

def initialize(attrs)
@changed = attrs[:changed]
@skipped = attrs[:skipped]
end
end
end
15 changes: 15 additions & 0 deletions lib/travis/api/v3/queries/organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ def update_billing_permission(user_id)
client.update_organization_billing_permission(params['organization.id'], data)
end

def suspend(value)
raise WrongParams, 'missing user ids'.freeze unless params['user_ids']&.size > 0

filtered_ids = filter_ids
Models::User.where("id in (?)", filtered_ids).update!(suspended: value, suspended_at: value ? Time.now.utc : nil)
Models::BulkChangeResult.new(
changed: filtered_ids,
skipped: params['user_ids'] - filtered_ids
)
end

def filter_ids
Membership.where(organization_id: id, user_id: params['user_ids']).all.map(&:user_id)
end

private

def provider
Expand Down
21 changes: 21 additions & 0 deletions lib/travis/api/v3/queries/users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Travis::API::V3
class Queries::Users < Query
params :user_ids

def suspend(value)
Models::User.where('id in (?)' , ids).update!(suspended: value, suspended_at: value ? Time.now.utc : nil)
Models::BulkChangeResult.new(
changed: ids - unknown_ids,
skipped: unknown_ids
)
end

def unknown_ids
@_unknown_ids ||= ids - User.where('id in (?)', ids).all.map(&:id)
end

def ids
@_ids ||= params['user_ids']
end
end
end
5 changes: 5 additions & 0 deletions lib/travis/api/v3/renderer/bulk_change_result.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Travis::API::V3
class Renderer::BulkChangeResult < ModelRenderer
representation(:standard, :changed,:skipped)
end
end
7 changes: 7 additions & 0 deletions lib/travis/api/v3/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ module Routes
route '/org/{organization.id}'
get :find
patch :update_billing_permission, '/update_billing_permission'
post :suspend, '/suspend'

resource :preferences do
route '/preferences'
Expand Down Expand Up @@ -375,6 +376,12 @@ module Routes
get :logout
end

resource :users do
route '/users'
post :suspend, '/suspend'
post :unsuspend, '/unsuspend'
end

resource :preferences do
route '/preferences'
get :for_user
Expand Down
1 change: 1 addition & 0 deletions lib/travis/api/v3/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ module Services
V2Subscriptions = Module.new { extend Services }
Trials = Module.new { extend Services }
User = Module.new { extend Services }
Users = Module.new { extend Services }
UserSetting = Module.new { extend Services }
UserSettings = Module.new { extend Services }

Expand Down
13 changes: 13 additions & 0 deletions lib/travis/api/v3/services/organization/suspend.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Travis::API::V3
class Services::Organization::Suspend < Service
params :id, :user_ids
result_type :bulk_change_result

def run!
raise LoginRequired unless access_control.full_access_or_logged_in?
raise WrongParams unless params.include? 'user_ids'

result query(:organization).suspend(true)
end
end
end
13 changes: 13 additions & 0 deletions lib/travis/api/v3/services/organization/unsuspend.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Travis::API::V3
class Services::Organization::Suspend < Service
params :id, :user_ids
result_type :bulk_change_result

def run!
raise LoginRequired unless access_control.full_access_or_logged_in?
raise WrongParams unless params.include? 'user_ids'

result query(:organization).suspend(false)
end
end
end
13 changes: 13 additions & 0 deletions lib/travis/api/v3/services/users/suspend.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Travis::API::V3
class Services::Users::Suspend < Service
params :user_ids
result_type :bulk_change_result

def run!
raise LoginRequired unless access_control.class.name == 'Travis::API::V3::AccessControl::Internal'
raise WrongParams unless params.include? 'user_ids'

result query(:users).suspend(true)
end
end
end
13 changes: 13 additions & 0 deletions lib/travis/api/v3/services/users/unsuspend.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Travis::API::V3
class Services::Users::Unsuspend < Service
params :user_ids
result_type :bulk_change_result

def run!
raise LoginRequired unless access_control.class.name == 'Travis::API::V3::AccessControl::Internal'
raise WrongParams unless params.include? 'user_ids'

result query(:users).suspend(false)
end
end
end
37 changes: 37 additions & 0 deletions spec/v3/services/organization/suspend_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
describe Travis::API::V3::Services::Organization::Suspend, set_app: true do
let(:organization_id) { 1 }
let(:organization) { FactoryBot.create(:org) }

context 'unauthenticated' do
it 'responds 403' do
post("/v3/org/#{organization_id}/suspend",JSON.generate({user_ids: [1,2,3]}))
expect(last_response.status).to eq(403)
end
end

describe 'authenticated' do
let(:user) { FactoryBot.create(:user) }
let(:user_to_suspend) { FactoryBot.create(:user) }
let(:another_user_to_suspend) { FactoryBot.create(:user) }
let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: 1) }
let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}",
'CONTENT_TYPE' => 'application/json' }}
context 'user is admin' do
before do
organization.memberships.create(user: user, role: 'admin')
organization.memberships.create(user: user_to_suspend, role: 'member')
organization.memberships.create(user: another_user_to_suspend, role: 'member')
end

it 'suspends the users' do
post("/v3/org/#{organization_id}/suspend", JSON.generate({user_ids: [user_to_suspend.id, another_user_to_suspend.id]}), headers)
expect(last_response.status).to eq(200)
expect(user_to_suspend.suspended)
expect(another_user_to_suspend.suspended)
post("/v3/org/#{organization_id}/unsuspend", JSON.generate({user_ids: [user_to_suspend.id]}), headers)
expect(!user_to_suspend.suspended)
expect(another_user_to_suspend.suspended)
end
end
end
end
33 changes: 33 additions & 0 deletions spec/v3/services/users/suspend_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
describe Travis::API::V3::Services::Organization::Suspend, set_app: true do
let(:organization_id) { 1 }
let(:organization) { FactoryBot.create(:org) }

context 'unauthenticated' do
it 'responds 403' do
post("/v3/users/suspend",JSON.generate({user_ids: [1,2,3]}))
expect(last_response.status).to eq(403)
end
end

describe 'authenticated' do
let(:internal_token) { 'FOO' }
let(:headers) { { 'HTTP_AUTHORIZATION' => "internal admin:#{internal_token}", 'CONTENT_TYPE' => 'application/json' } }
around do |ex|
apps = Travis.config.applications
Travis.config.applications = { 'admin' => { token: internal_token, full_access: true }}
ex.run
Travis.config.applications = apps
end
let(:user_to_suspend) { FactoryBot.create(:user) }
let(:another_user_to_suspend) { FactoryBot.create(:user) }
it 'suspends the users' do
post("/v3/users/suspend",JSON.generate({user_ids: [user_to_suspend.id, another_user_to_suspend.id]}), headers)
expect(last_response.status).to eq(200)
expect(user_to_suspend.suspended)
expect(another_user_to_suspend.suspended)
post("/v3/users/unsuspend", JSON.generate({user_ids: [user_to_suspend.id]}), headers)
expect(!user_to_suspend.suspended)
expect(another_user_to_suspend.suspended)
end
end
end