diff --git a/lib/travis/api/app/endpoint/logs.rb b/lib/travis/api/app/endpoint/logs.rb index 6160df95f5..f00c45ec77 100644 --- a/lib/travis/api/app/endpoint/logs.rb +++ b/lib/travis/api/app/endpoint/logs.rb @@ -14,8 +14,13 @@ class Logs < Endpoint repo = Travis::API::V3::Models::Repository.find(job.repository.id) repo_can_write = current_user ? !!repo.users.where(id: current_user.id, permissions: { push: true }).first : false - raise LogExpired 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 - raise LogAccessDenied if repo.user_settings.job_log_access_based_limit && !repo_can_write + 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 + halt 403, { error: { message: "We're sorry, but this data is not available anymore. Please check the repository settings in Travis CI." } } + end + + if repo.user_settings.job_log_access_based_limit && !repo_can_write + halt 403, { error: { message: "We're sorry, but this data is not available. Please check the repository settings in Travis CI." } } + end if !resource || ((job.try(:private?) || !allow_public?) && !has_permission?(job)) halt 404 diff --git a/lib/travis/api/v3/access_control/log_token.rb b/lib/travis/api/v3/access_control/log_token.rb index 91effec0ce..3da47dfc42 100644 --- a/lib/travis/api/v3/access_control/log_token.rb +++ b/lib/travis/api/v3/access_control/log_token.rb @@ -5,7 +5,7 @@ module Travis::API::V3 class AccessControl::LogToken < AccessControl::Generic auth_type('log.token') - attr_accessor :token + attr_accessor :token, :repo_can_write def self.for_request(type, token, env) new(token) @@ -13,6 +13,7 @@ def self.for_request(type, token, env) def initialize(token) self.token = token + self.repo_can_write = Travis::API::V3::LogToken.find(token).repo_can_write end def temp_access? diff --git a/lib/travis/api/v3/log_token.rb b/lib/travis/api/v3/log_token.rb index cfea1a20af..7ed7201696 100644 --- a/lib/travis/api/v3/log_token.rb +++ b/lib/travis/api/v3/log_token.rb @@ -1,14 +1,18 @@ module Travis::API::V3 class LogToken - attr_accessor :job_id + attr_accessor :job_id, :repo_can_write def self.find(token) - new(redis.get("l:#{token}").to_i) + key = "l:#{token}" + new(redis.hget(key, :job_id).to_i, !!redis.hget(key, :repo_can_write)) end - def self.create(job) + def self.create(job, user_id) + repo_can_write = !!job.repository.users.where(id: user_id, permissions: { push: true }).first + token = SecureRandom.urlsafe_base64(16) - redis.set("l:#{token}", job.id) + redis.hset("l:#{token}", :job_id, job.id) + redis.hset("l:#{token}", :repo_can_write, repo_can_write) redis.expire("l:#{token}", 1.day) token end @@ -17,8 +21,9 @@ def self.redis Travis.redis end - def initialize(job_id) + def initialize(job_id, repo_can_write) self.job_id = job_id + self.repo_can_write = repo_can_write end def matches?(job) diff --git a/lib/travis/api/v3/models/log.rb b/lib/travis/api/v3/models/log.rb index 5f40f89c4d..2989d63124 100644 --- a/lib/travis/api/v3/models/log.rb +++ b/lib/travis/api/v3/models/log.rb @@ -27,6 +27,10 @@ def repository_private? job.repository.private? end + def repository + @repository ||= Travis::API::V3::Models::Repository.find(job.repository.id) + end + private def archived_log_part diff --git a/lib/travis/api/v3/renderer/log.rb b/lib/travis/api/v3/renderer/log.rb index 603ad59896..459f3e7f1e 100644 --- a/lib/travis/api/v3/renderer/log.rb +++ b/lib/travis/api/v3/renderer/log.rb @@ -25,8 +25,8 @@ def render(representation) if raw_log_href !~ /^\/v3/ raw_log_href = "/v3#{raw_log_href}" end - if enterprise? || model.repository_private? - token = LogToken.create(model.job) + if enterprise? || model.repository_private? || model.repository.user_settings.job_log_access_based_limit + token = LogToken.create(model.job, access_control&.user&.id) raw_log_href += "?log.token=#{token}" end result['@raw_log_href'] = raw_log_href diff --git a/lib/travis/api/v3/services/log/find.rb b/lib/travis/api/v3/services/log/find.rb index 040f59ee40..0878bf8a26 100644 --- a/lib/travis/api/v3/services/log/find.rb +++ b/lib/travis/api/v3/services/log/find.rb @@ -4,11 +4,16 @@ class Services::Log::Find < Service def run! job = Models::Job.find(params['job.id']) - repo_can_write = access_control.user ? !!job.repository.users.where(id: access_control.user.id, permissions: { push: true }).first : false - log = query.find(job) + repo_can_write = false + if access_control.is_a?(Travis::API::V3::AccessControl::LogToken) + repo_can_write = access_control.repo_can_write + elsif access_control.user + repo_can_write = !!job.repository.users.where(id: access_control.user.id, permissions: { push: true }).first + end + raise(NotFound, :log) unless access_control.visible? log - raise LogExpired if job.repository.user_settings.job_log_time_based_limit && job.started_at && job.started_at < Time.now - job.repository.user_settings.job_log_access_older_than_days.days + raise LogExpired if !job.repository.user_settings.job_log_time_based_limit && job.started_at && job.started_at < Time.now - job.repository.user_settings.job_log_access_older_than_days.days raise LogAccessDenied if job.repository.user_settings.job_log_access_based_limit && !repo_can_write result log diff --git a/spec/auth/v1/logs_spec.rb b/spec/auth/v1/logs_spec.rb index 3a9efddf9d..1e2ea54378 100644 --- a/spec/auth/v1/logs_spec.rb +++ b/spec/auth/v1/logs_spec.rb @@ -6,7 +6,12 @@ let(:log) { double(id: 1) } let(:log_url) { "#{Travis.config[:logs_api][:url]}/logs/1?by=id&source=api" } - before { stub_request(:get, log_url).to_return(status: 200, body: %({"job_id": #{job.id}, "content": "content"})) } + before do + stub_request(:get, log_url).to_return(status: 200, body: %({"job_id": #{job.id}, "content": "content"})) + repository = Travis::API::V3::Models::Repository.find(repo.id) + repository.user_settings.update(:job_log_time_based_limit, true) + repository.save! + end describe 'in public mode, with a private repo', mode: :public, repo: :private do describe 'GET /logs/%{log.id}' do diff --git a/spec/auth/v2.1/logs_spec.rb b/spec/auth/v2.1/logs_spec.rb index a65a797bea..588676c093 100644 --- a/spec/auth/v2.1/logs_spec.rb +++ b/spec/auth/v2.1/logs_spec.rb @@ -32,6 +32,9 @@ allow(remote).to receive(:find_by_job_id).and_return(Travis::RemoteLog.new(log_from_api)) allow(remote).to receive(:find_by_id).and_return(Travis::RemoteLog.new(log_from_api)) allow(remote).to receive(:fetch_archived_log_content).and_return(archived_content) + repository = Travis::API::V3::Models::Repository.find(repo.id) + repository.user_settings.update(:job_log_time_based_limit, true) + repository.save! end describe 'in public mode, with a private repo', mode: :public, repo: :private do diff --git a/spec/auth/v2/logs_spec.rb b/spec/auth/v2/logs_spec.rb index 2ba65afc75..cae31da587 100644 --- a/spec/auth/v2/logs_spec.rb +++ b/spec/auth/v2/logs_spec.rb @@ -32,6 +32,9 @@ allow(remote).to receive(:find_by_job_id).and_return(Travis::RemoteLog.new(log_from_api)) allow(remote).to receive(:find_by_id).and_return(Travis::RemoteLog.new(log_from_api)) allow(remote).to receive(:fetch_archived_log_content).and_return(archived_content) + repository = Travis::API::V3::Models::Repository.find(repo.id) + repository.user_settings.update(:job_log_time_based_limit, true) + repository.save! end describe 'in public mode, with a private repo', mode: :public, repo: :private do diff --git a/spec/integration/visibility_spec.rb b/spec/integration/visibility_spec.rb index ae6afb023a..d57fa5ecc2 100644 --- a/spec/integration/visibility_spec.rb +++ b/spec/integration/visibility_spec.rb @@ -16,6 +16,11 @@ before { requests[0].update_attributes(private: false) } before { builds[0].update_attributes(private: false) } before { jobs[0].update_attributes(private: false) } + before do + repository = Travis::API::V3::Models::Repository.find(repo.id) + repository.user_settings.update(:job_log_time_based_limit, true) + repository.save! + end before :each do Fog.mock! storage = Fog::Storage.new({ diff --git a/spec/v3/services/job/find_spec.rb b/spec/v3/services/job/find_spec.rb index edcbe18cb5..b2bcf3a437 100644 --- a/spec/v3/services/job/find_spec.rb +++ b/spec/v3/services/job/find_spec.rb @@ -141,7 +141,7 @@ end describe "fetching job on private repository, private API, with a log.token" do - let(:log_token) { Travis::API::V3::LogToken.create(job).to_s } + let(:log_token) { Travis::API::V3::LogToken.create(job, owner.id).to_s } before { repo.update_attribute(:private, true) } before { get("/v3/job/#{job.id}?log.token=#{log_token}", {}, {}) } after { repo.update_attribute(:private, false) } diff --git a/spec/v3/services/log/find_spec.rb b/spec/v3/services/log/find_spec.rb index cf19db14ad..f3fe17a2c7 100644 --- a/spec/v3/services/log/find_spec.rb +++ b/spec/v3/services/log/find_spec.rb @@ -224,7 +224,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, true) + user_settings.update(:job_log_time_based_limit, false) user_settings.update(:job_log_access_based_limit, false) end @@ -255,7 +255,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, true) + user_settings.update(:job_log_time_based_limit, false) user_settings.update(:job_log_access_based_limit, true) end @@ -313,7 +313,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, false) + user_settings.update(:job_log_time_based_limit, true) user_settings.update(:job_log_access_based_limit, true) end @@ -367,7 +367,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, false) + user_settings.update(:job_log_time_based_limit, true) user_settings.update(:job_log_access_based_limit, false) end @@ -399,7 +399,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, true) + user_settings.update(:job_log_time_based_limit, false) user_settings.update(:job_log_access_based_limit, false) end @@ -435,7 +435,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, true) + user_settings.update(:job_log_time_based_limit, false) user_settings.update(:job_log_access_based_limit, true) end @@ -494,7 +494,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, false) + user_settings.update(:job_log_time_based_limit, true) user_settings.update(:job_log_access_based_limit, true) end @@ -549,7 +549,7 @@ user_settings = Travis::API::V3::Models::Repository.find(repo.id).user_settings user_settings.user = user user_settings.change_source = 'travis-api' - user_settings.update(:job_log_time_based_limit, false) + user_settings.update(:job_log_time_based_limit, true) user_settings.update(:job_log_access_based_limit, false) end