Skip to content

Commit 179f067

Browse files
authored
fix(guard): remove token cache from repo host account (#153)
1 parent 6349685 commit 179f067

File tree

16 files changed

+114
-77
lines changed

16 files changed

+114
-77
lines changed

ee/rbac/lib/rbac/front_repo/repo_host_account.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ defmodule Rbac.FrontRepo.RepoHostAccount do
4646
field(:permission_scope, :string)
4747
field(:token, :string)
4848
field(:refresh_token, :string)
49+
field(:token_expires_at, :utc_datetime)
4950
field(:revoked, :boolean, default: false)
5051

5152
timestamps(inserted_at: :created_at, updated_at: :updated_at, type: :utc_datetime)

ee/rbac/priv/front_repo/migrations/20220314144013_create_repo_host_accounts.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ defmodule Rbac.FrontRepo.Migrations.CreateRepoHostAccounts do
1313
add :permission_scope, :string
1414
add :revoked, :boolean, default: false, null: false
1515
add :refresh_token, :string
16+
add :token_expires_at, :utc_datetime
1617
add :created_at, :utc_datetime
1718
add :updated_at, :utc_datetime
1819
end

github_hooks/Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ gem "sentry-rails"
3232
gem "sentry-sidekiq"
3333

3434
gem "sprockets", "< 4"
35-
gem "nokogiri", "~> 1.18.3"
35+
gem "nokogiri", "~> 1.18.4"
3636

3737
gem "rt-watchman", :require => "watchman", :github => "renderedtext/watchman", :ref => "74530687a232aea678b6738114c82dfc163657cd"
3838
gem "rt-logman", :require => "logman"

github_hooks/Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ GEM
221221
net-smtp (0.5.0)
222222
net-protocol
223223
nio4r (2.7.4)
224-
nokogiri (1.18.3)
224+
nokogiri (1.18.5)
225225
mini_portile2 (~> 2.8.2)
226226
racc (~> 1.4)
227227
octokit (4.20.0)
@@ -466,7 +466,7 @@ DEPENDENCIES
466466
kaminari (~> 1.2.2)
467467
lograge
468468
net-http
469-
nokogiri (~> 1.18.3)
469+
nokogiri (~> 1.18.4)
470470
octokit
471471
pg (~> 1.1)
472472
pry-byebug (~> 3.10, >= 3.10.1)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddTokenExpiresAtToRepoHostAccounts < ActiveRecord::Migration[5.1]
2+
def change
3+
add_column :repo_host_accounts, :token_expires_at, :datetime, null: true, default: nil
4+
end
5+
end

guard/lib/guard/api/bitbucket.ex

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,10 @@ defmodule Guard.Api.Bitbucket do
3535
Fetch or refresh access token
3636
"""
3737
def user_token(repo_host_account) do
38-
cache_key = OAuth.token_cache_key(repo_host_account)
39-
40-
case Cachex.get(:token_cache, cache_key) do
41-
{:ok, {token, expires_at}} when not is_nil(token) and token != "" ->
42-
if OAuth.valid_token?(expires_at) do
43-
{:ok, {token, expires_at}}
44-
else
45-
fetch_and_cache_token(repo_host_account)
46-
end
47-
48-
_ ->
49-
fetch_and_cache_token(repo_host_account)
38+
if OAuth.valid_token?(repo_host_account.token_expires_at, nil_valid: false) do
39+
{:ok, {repo_host_account.token, repo_host_account.token_expires_at}}
40+
else
41+
fetch_token(repo_host_account)
5042
end
5143
end
5244

@@ -63,7 +55,12 @@ defmodule Guard.Api.Bitbucket do
6355
end
6456
end
6557

66-
defp fetch_and_cache_token(repo_host_account) do
58+
defp fetch_token(%{refresh_token: refresh_token}) when refresh_token in [nil, ""] do
59+
Logger.warning("No refresh token found for Bitbucket repo host account, account is revoked")
60+
{:error, :revoked}
61+
end
62+
63+
defp fetch_token(repo_host_account) do
6764
body_params = %{
6865
"grant_type" => "refresh_token",
6966
"refresh_token" => repo_host_account.refresh_token

guard/lib/guard/api/github.ex

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ defmodule Guard.Api.Github do
3636

3737
@doc """
3838
Fetch or refresh access token
39+
40+
# Important Considerations:
41+
- By default, GitHub tokens do not expire unless the optional setting in the GitHub app is changed.
42+
- If altered, the expires_in and refresh_token will not be null.
43+
- That's why we have refresh token logic for GitHub, even if it's not typically used.
3944
"""
4045
def user_token(repo_host_account) do
4146
case validate_token(repo_host_account.token) do
@@ -44,6 +49,11 @@ defmodule Guard.Api.Github do
4449
end
4550
end
4651

52+
defp handle_fetch_token(%{refresh_token: refresh_token}) when refresh_token in [nil, ""] do
53+
Logger.warning("No refresh token found for GitHub repo host account, account is revoked")
54+
{:error, :revoked}
55+
end
56+
4757
defp handle_fetch_token(repo_host_account) do
4858
{:ok, {client_id, client_secret}} = Guard.GitProviderCredentials.get(:github)
4959

@@ -58,7 +68,7 @@ defmodule Guard.Api.Github do
5868

5969
case Tesla.post(client, @oauth_path, nil, query: query_params) do
6070
{:ok, %Tesla.Env{status: status, body: body}} when status in 200..299 ->
61-
OAuth.handle_ok_token_response(repo_host_account, body, cache: false)
71+
OAuth.handle_ok_token_response(repo_host_account, body)
6272

6373
{:ok, %Tesla.Env{status: status}} when status in 400..499 ->
6474
Logger.warning("Failed to refresh github token, account might be revoked")

guard/lib/guard/api/gitlab.ex

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,10 @@ defmodule Guard.Api.Gitlab do
1111
Fetch or refresh access token
1212
"""
1313
def user_token(repo_host_account) do
14-
cache_key = OAuth.token_cache_key(repo_host_account)
15-
16-
case Cachex.get(:token_cache, cache_key) do
17-
{:ok, {token, expires_at}} when not is_nil(token) and token != "" ->
18-
if OAuth.valid_token?(expires_at) do
19-
{:ok, {token, expires_at}}
20-
else
21-
handle_fetch_and_cache_token(repo_host_account)
22-
end
23-
24-
_ ->
25-
handle_fetch_and_cache_token(repo_host_account)
14+
if OAuth.valid_token?(repo_host_account.token_expires_at, nil_valid: false) do
15+
{:ok, {repo_host_account.token, repo_host_account.token_expires_at}}
16+
else
17+
handle_fetch_token(repo_host_account)
2618
end
2719
end
2820

@@ -32,15 +24,20 @@ defmodule Guard.Api.Gitlab do
3224
case Tesla.get(client, @oauth_token_info_path) do
3325
{:ok, res} ->
3426
expires_at = OAuth.calc_expires_at(res.body["expires_in"])
35-
{:ok, res.status in 200..299 && OAuth.valid_token?(expires_at)}
27+
{:ok, res.status in 200..299 && OAuth.valid_token?(expires_at, nil_valid: false)}
3628

3729
{:error, error} ->
3830
Logger.error("Error validating token: #{inspect(error)}")
3931
{:error, :network_error}
4032
end
4133
end
4234

43-
defp handle_fetch_and_cache_token(repo_host_account) do
35+
defp handle_fetch_token(%{refresh_token: refresh_token}) when refresh_token in [nil, ""] do
36+
Logger.warning("No refresh token found for GitLab repo host account, account is revoked")
37+
{:error, :revoked}
38+
end
39+
40+
defp handle_fetch_token(repo_host_account) do
4441
body_params = %{
4542
"grant_type" => "refresh_token",
4643
"refresh_token" => repo_host_account.refresh_token,

guard/lib/guard/application.ex

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,6 @@ defmodule Guard.Application do
144144
worker: Supervisor.child_spec({Cachex, :ppl_cache}, id: :ppl_cache),
145145
active: true
146146
},
147-
%{
148-
worker: Supervisor.child_spec({Cachex, :token_cache}, id: :token_cache),
149-
active: true
150-
},
151147
%{
152148
worker:
153149
Supervisor.child_spec({Cachex, :feature_provider_cache}, id: :feature_provider_cache),

guard/lib/guard/front_repo/repo_host_account.ex

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ defmodule Guard.FrontRepo.RepoHostAccount do
4646
field(:permission_scope, :string)
4747
field(:token, :string)
4848
field(:refresh_token, :string)
49+
field(:token_expires_at, :utc_datetime)
4950
field(:revoked, :boolean, default: false)
5051

5152
timestamps(inserted_at: :created_at, updated_at: :updated_at, type: :utc_datetime)
@@ -184,8 +185,14 @@ defmodule Guard.FrontRepo.RepoHostAccount do
184185
end
185186
end
186187

187-
def update_token_pair(rha, token, refresh_token) do
188-
update_account(%{token: token, refresh_token: refresh_token}, rha)
188+
def update_token(rha, token, refresh_token, expires_at) do
189+
params = %{
190+
token: token,
191+
refresh_token: refresh_token,
192+
token_expires_at: expires_at
193+
}
194+
195+
update_account(params, rha)
189196
end
190197

191198
@spec get_uid_by_login(String.t(), String.t()) :: {:ok, String.t()} | {:error, :not_found}
@@ -314,6 +321,7 @@ defmodule Guard.FrontRepo.RepoHostAccount do
314321
:revoked,
315322
:token,
316323
:refresh_token,
324+
:token_expires_at,
317325
:permission_scope
318326
]
319327
)

0 commit comments

Comments
 (0)