Skip to content

Commit bbea94b

Browse files
committed
Merge branch 'master' into bugfix_cycle_12
2 parents 4d3de0d + cfcd61a commit bbea94b

File tree

29 files changed

+575
-129
lines changed

29 files changed

+575
-129
lines changed

lib/travis.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class GithubApiError < StandardError; end
3131
class AdminMissing < StandardError; end
3232
class RepositoryMissing < StandardError; end
3333
class LogAlreadyRemoved < StandardError; end
34+
class LogExpired < StandardError; end
35+
class LogAccessDenied < StandardError; end
3436
class AuthorizationDenied < StandardError; end
3537
class JobUnfinished < StandardError; end
3638

lib/travis/api/app/endpoint/jobs.rb

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,7 @@ class Jobs < Endpoint
9393
# the way we use responders makes it hard to validate proper format
9494
# automatically here, so we need to check it explicitly
9595
if accepts?('text/plain')
96-
archived_log_path = resource.archived_url
97-
98-
if params[:cors_hax]
99-
status 204
100-
headers['Access-Control-Expose-Headers'] = 'Location'
101-
headers['Location'] = archived_log_path
102-
attach_log_token if job.try(:private?)
103-
else
104-
redirect archived_log_path, 307
105-
end
96+
respond_with resource.archived_log_content
10697
elsif accepts?('application/json')
10798
attach_log_token if job.try(:private?)
10899
respond_with resource.as_json

lib/travis/api/app/endpoint/logs.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ class Logs < Endpoint
99
resource = service(:find_log, id: params[:id]).run
1010
job = resource ? Job.find(resource.job_id) : nil
1111

12+
halt 404 unless job
13+
14+
repo = Travis::API::V3::Models::Repository.find(job.repository.id)
15+
repo_can_write = current_user ? !!repo.users.where(id: current_user.id, permissions: { push: true }).first : false
16+
17+
if !repo.user_settings.job_log_time_based_limit && job.started_at && job.started_at < Time.now - repo.user_settings.job_log_access_older_than_days.days
18+
halt 403, { error: { message: "We're sorry, but this data is not available anymore. Please check the repository settings in Travis CI." } }
19+
end
20+
21+
if repo.user_settings.job_log_access_based_limit && !repo_can_write
22+
halt 403, { error: { message: "We're sorry, but this data is not available. Please check the repository settings in Travis CI." } }
23+
end
24+
1225
if !resource || ((job.try(:private?) || !allow_public?) && !has_permission?(job))
1326
halt 404
1427
elsif resource.removed_at && accepts?('application/json')
@@ -17,7 +30,7 @@ class Logs < Endpoint
1730
# the way we use responders makes it hard to validate proper format
1831
# automatically here, so we need to check it explicitly
1932
if accepts?('text/plain')
20-
redirect resource.archived_url, 307
33+
respond_with resource.archived_log_content
2134
elsif accepts?('application/json')
2235
respond_with resource.as_json
2336
else

lib/travis/api/v3.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ def location(env)
3939
JobNotCancelable = ClientError .create('job is not running, cannot cancel', status: 409)
4040
JobUnfinished = ClientError .create('job still running, cannot remove log yet', status: 409)
4141
LogAlreadyRemoved = ClientError .create('log has already been removed', status: 409)
42+
LogExpired = ClientError .create("We're sorry, but this data is not available anymore. Please check the repository settings in Travis CI.", status: 403)
43+
LogAccessDenied = ClientError .create("We're sorry, but this data is not available. Please check the repository settings in Travis CI.", status: 403)
4244
LoginRequired = ClientError .create('login required', status: 403)
4345
MethodNotAllowed = ClientError .create('method not allowed', status: 405)
4446
NotImplemented = ServerError .create('request not (yet) implemented', status: 501)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ module Travis::API::V3
55
class AccessControl::LogToken < AccessControl::Generic
66
auth_type('log.token')
77

8-
attr_accessor :token
8+
attr_accessor :token, :repo_can_write
99

1010
def self.for_request(type, token, env)
1111
new(token)
1212
end
1313

1414
def initialize(token)
1515
self.token = token
16+
self.repo_can_write = Travis::API::V3::LogToken.find(token).repo_can_write
1617
end
1718

1819
def temp_access?

lib/travis/api/v3/log_token.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
module Travis::API::V3
22
class LogToken
3-
attr_accessor :job_id
3+
attr_accessor :job_id, :repo_can_write
44

55
def self.find(token)
6-
new(redis.get("l:#{token}").to_i)
6+
key = "l:#{token}"
7+
new(redis.hget(key, :job_id).to_i, !!redis.hget(key, :repo_can_write))
78
end
89

9-
def self.create(job)
10+
def self.create(job, user_id)
11+
repo_can_write = !!job.repository.users.where(id: user_id, permissions: { push: true }).first
12+
1013
token = SecureRandom.urlsafe_base64(16)
11-
redis.set("l:#{token}", job.id)
14+
redis.hset("l:#{token}", :job_id, job.id)
15+
redis.hset("l:#{token}", :repo_can_write, repo_can_write)
1216
redis.expire("l:#{token}", 1.day)
1317
token
1418
end
@@ -17,8 +21,9 @@ def self.redis
1721
Travis.redis
1822
end
1923

20-
def initialize(job_id)
24+
def initialize(job_id, repo_can_write)
2125
self.job_id = job_id
26+
self.repo_can_write = repo_can_write
2227
end
2328

2429
def matches?(job)

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Travis::API::V3
2+
class Models::Audit < Model
3+
belongs_to :owner, polymorphic: true
4+
belongs_to :source, polymorphic: true
5+
end
6+
end

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
module Travis::API::V3
44
class Models::JsonSlice
5-
include Virtus.model, Enumerable, Models::JsonSync, ActiveModel::Validations
5+
include Virtus.model, Enumerable, Models::JsonSync, ActiveModel::Validations, ActiveSupport::Callbacks, ActiveModel::Dirty
6+
extend ActiveSupport::Concern
7+
define_callbacks :after_save
68

79
class << self
810
attr_accessor :child_klass
@@ -30,14 +32,21 @@ def read(name)
3032

3133
def update(name, value)
3234
raise NotFound unless respond_to?(:"#{name}=")
35+
@changes = { :"#{name}" => { before: send(name), after: value } } unless value == send(name)
3336
send(:"#{name}=", value)
3437
raise UnprocessableEntity, errors.full_messages.to_sentence unless valid?
3538
sync!
39+
run_callbacks :after_save
40+
@changes = {}
3641
read(name)
3742
end
3843

3944
def to_h
4045
Hash[map { |x| [x.name, x.value] }]
4146
end
47+
48+
def changes
49+
@changes
50+
end
4251
end
4352
end

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ def repository_private?
2727
job.repository.private?
2828
end
2929

30+
def repository
31+
@repository ||= Travis::API::V3::Models::Repository.find(job.repository.id)
32+
end
33+
3034
private
3135

3236
def archived_log_part

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,20 @@ class Models::UserSettings < Models::JsonSlice
1212
attribute :config_validation, Boolean, default: lambda { |us, _| us.config_validation? }
1313
attribute :share_encrypted_env_with_forks, Boolean, default: false
1414
attribute :share_ssh_keys_with_forks, Boolean, default: lambda { |us, _| us.share_ssh_keys_with_forks? }
15+
attribute :job_log_time_based_limit, Boolean, default: lambda { |s, _| s.job_log_access_permissions[:time_based_limit] }
16+
attribute :job_log_access_based_limit, Boolean, default: lambda { |s, _| s.job_log_access_permissions[:access_based_limit] }
17+
attribute :job_log_access_older_than_days, Integer, default: lambda { |s, _| s.job_log_access_permissions[:older_than_days] }
18+
19+
validates :job_log_access_older_than_days, numericality: true
20+
21+
validate :job_log_access_older_than_days_restriction
22+
23+
set_callback :after_save, :after, :save_audit
1524

1625
attr_reader :repo
1726

27+
attr_accessor :user, :change_source
28+
1829
def initialize(repo, data)
1930
@repo = repo
2031
super(data)
@@ -57,5 +68,24 @@ def cutoff_date
5768
def days_since_jan_15
5869
Date.today.mjd - JAN_15.mjd + 1
5970
end
71+
72+
def job_log_access_permissions
73+
Travis.config.to_h.fetch(:job_log_access_permissions) { {} }
74+
end
75+
76+
def job_log_access_older_than_days_restriction
77+
if job_log_access_older_than_days.to_i > job_log_access_permissions[:max_days_value] ||
78+
job_log_access_older_than_days.to_i < job_log_access_permissions[:min_days_value]
79+
errors.add(:job_log_access_older_than_days, "is outside the bounds")
80+
end
81+
end
82+
83+
private
84+
85+
def save_audit
86+
if self.change_source
87+
Travis::API::V3::Models::Audit.create!(owner: self.user, change_source: self.change_source, source: self.repo, source_changes: { settings: self.changes })
88+
end
89+
end
6090
end
6191
end

0 commit comments

Comments
 (0)