Skip to content

Commit 72140d5

Browse files
Release 2025 03 05
Release 2025 03 05
2 parents 3a9fadc + d1e46f9 commit 72140d5

32 files changed

+489
-15
lines changed

lib/travis/api/app/endpoint.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def authorizer
117117
end
118118

119119
def auth_for_repo(id, type)
120+
current_user&.touch
120121
permission = authorizer.for_repo(id, type)
121122
halt 403, { error: { message: "We're sorry, but you're not authorized to perform this request" } } unless permission
122123
rescue Travis::API::V3::AuthorizerError
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require 'travis/api/v3/access_control/generic'
2+
3+
module Travis::API::V3
4+
class AccessControl::OrgToken < AccessControl::Generic
5+
auth_type('org.token')
6+
7+
attr_accessor :org, :token
8+
9+
def self.for_request(type, token, env)
10+
new(token)
11+
end
12+
13+
def initialize(token)
14+
if token.is_a? Array
15+
self.org = token.first
16+
self.token = token.last
17+
elsif token.include?(':')
18+
self.org = token.split(':')&.first
19+
self.token = token.split(':')&.last
20+
else
21+
self.org = Models::OrganizationToken.find_by(token: self.token)&.organization_id
22+
self.token = token
23+
end
24+
end
25+
26+
def visible?(object, type = nil)
27+
return Models::OrganizationToken.where(organization: org).joins(:organization_token_permissions).where(organization_token_permissions: {permission: object})&.first&.token&.split(':')&.last == token
28+
end
29+
30+
def logged_in?
31+
false
32+
end
33+
34+
def full_access?
35+
false
36+
end
37+
end
38+
end

lib/travis/api/v3/access_control/user.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class AccessControl::User < AccessControl::Generic
77
def initialize(user)
88
user = Models::User.find(user.id) if user.is_a? ::User
99
@user = user
10+
user.touch
1011
@access_permissions = user.permissions.where(user_id: user.id)
1112
super()
1213
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Travis::API::V3
2+
class Models::BulkChangeResult
3+
attr_accessor :changed, :skipped
4+
5+
def initialize(attrs)
6+
@changed = attrs[:changed]
7+
@skipped = attrs[:skipped]
8+
end
9+
end
10+
end

lib/travis/api/v3/models/cron.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def enqueue
6666
)
6767

6868
update_attribute(:last_run, DateTime.now.utc)
69+
update_activity
6970
schedule_next_build
7071
end
7172

@@ -82,6 +83,15 @@ def deactivate
8283
update!(active: false)
8384
end
8485

86+
def update_activity
87+
owner = branch.repository.owner
88+
owner&.touch if owner.is_a? Models::User
89+
build = Build.find_by_id(branch.last_build_id)
90+
if build && build.sender_type == 'User' && build.sender_id > 0
91+
Models::User.find(build.sender_id)&.touch
92+
end
93+
end
94+
8595
def deactivate_and_log_reason(reason)
8696
Travis.logger.info "Removing cron #{self.id} because the associated #{reason}"
8797
deactivate
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module Travis::API::V3
2+
class Models::OrganizationToken < Model
3+
belongs_to :organization
4+
has_many :organization_token_permissions
5+
6+
serialize :token, Travis::Model::EncryptedColumn.new
7+
end
8+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Travis::API::V3
2+
class Models::OrganizationTokenPermission < Model
3+
belongs_to :organization_token
4+
end
5+
end

lib/travis/api/v3/models/user.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ def installation
8787
@installation = Models::Installation.find_by(owner_type: 'User', owner_id: id, removed_by_id: nil)
8888
end
8989

90+
def touch
91+
update(last_activity_at: Time.now) if last_activity_at.nil? || Time.now.utc - last_activity_at > 300
92+
end
93+
9094
def internal?
9195
!!get_internal_user
9296
end

lib/travis/api/v3/queries/organization.rb

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,50 @@ def update_billing_permission(user_id)
1919
client.update_organization_billing_permission(params['organization.id'], data)
2020
end
2121

22+
def active(value, from)
23+
org = Models::Organization.find_by_id(id) if id
24+
from ||= Time.now - 1.day
25+
sort Models::User.where('id in (?)', org.memberships.pluck(:user_id)).where("users.last_activity_at #{value ? '>' : '<'} ?", from)
26+
end
27+
28+
def suspend(value)
29+
if params['vcs_type']
30+
raise WrongParams, 'missing user ids'.freeze unless params['vcs_ids']&.size > 0
31+
32+
user_ids = Models::User.where("vcs_type = ? and vcs_id in (?)", vcs_type,params['vcs_ids']).all.map(&:id)
33+
else
34+
raise WrongParams, 'missing user ids'.freeze unless params['user_ids']&.size > 0
35+
36+
user_ids = params['user_ids']
37+
end
38+
39+
filtered_ids = filter_ids(user_ids)
40+
Models::User.where("id in (?)", filtered_ids).update!(suspended: value, suspended_at: value ? Time.now.utc : nil)
41+
Models::BulkChangeResult.new(
42+
changed: filtered_ids,
43+
skipped: user_ids - filtered_ids
44+
)
45+
end
46+
47+
def filter_ids(ids)
48+
Membership.where(organization_id: id, user_id: ids).all.map(&:user_id)
49+
end
50+
51+
def vcs_type
52+
@_vcs_type ||=
53+
params['vcs_type'] ?
54+
(
55+
params['vcs_type'].end_with?('User') ?
56+
params['vcs_type'] :
57+
"#{params['vcs_type'].capitalize}User"
58+
)
59+
: 'GithubUser'
60+
end
61+
2262
private
2363

2464
def provider
2565
params['provider'] || 'github'
2666
end
27-
2867
end
2968
end

lib/travis/api/v3/queries/users.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module Travis::API::V3
2+
class Queries::Users < Query
3+
params :user_ids, :vcs_ids, :vcs_type
4+
5+
def suspend(value)
6+
if params['vcs_type']
7+
raise WrongParams, 'missing user ids'.freeze unless params['vcs_ids']&.size > 0
8+
9+
ids = Models::User.where("vcs_type = ? and vcs_id in (?)", vcs_type, params['vcs_ids']).all.map(&:id)
10+
else
11+
raise WrongParams, 'missing user ids'.freeze unless params['user_ids']&.size > 0
12+
13+
ids = params['user_ids']
14+
end
15+
Models::User.where('id in (?)' , ids).update!(suspended: value, suspended_at: value ? Time.now.utc : nil)
16+
skipped = unknown_ids(ids)
17+
Models::BulkChangeResult.new(
18+
changed: ids - skipped,
19+
skipped: skipped
20+
)
21+
end
22+
23+
def unknown_ids(ids)
24+
@_unknown_ids ||= ids - User.where('id in (?)', ids).all.map(&:id)
25+
end
26+
27+
private
28+
29+
def vcs_type
30+
@_vcs_type ||=
31+
params['vcs_type'] ?
32+
(
33+
params['vcs_type'].end_with?('User') ?
34+
params['vcs_type'] :
35+
"#{params['vcs_type'].capitalize}User"
36+
)
37+
: 'GithubUser'
38+
end
39+
end
40+
end

0 commit comments

Comments
 (0)