Skip to content

Commit

Permalink
Fix oauth tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vtm9 committed Oct 3, 2024
1 parent fd872e0 commit 3856424
Show file tree
Hide file tree
Showing 13 changed files with 383 additions and 347 deletions.
59 changes: 28 additions & 31 deletions services/app/apps/codebattle/lib/codebattle/auth/discord.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ defmodule Codebattle.Auth.Discord do

@discord_auth_url "https://discord.com/oauth2/authorize"
@discord_token_url "https://discord.com/api/v10/oauth2/token"

@http_client Application.compile_env(:codebattle, :discord_oauth_client)

@doc """
`http_client/0` injects a TestDouble of Req in Test
"""
def http_client, do: @http_client
@discord_user_url "https://discord.com/api/users/@me"

@doc """
`client_id/0` returns a `String` of the `DISCORD_CLIENT_ID`
Expand Down Expand Up @@ -52,23 +46,23 @@ defmodule Codebattle.Auth.Discord do
Bad authentication codes will return a tuple with `:error` and an error map.
"""
def discord_auth(code, redirect_uri) do
query =
URI.encode_query(%{
client_id: client_id(),
client_secret: client_secret(),
grant_type: "authorization_code",
code: code,
redirect_uri: redirect_uri
})

http_client().post!(@discord_token_url <> query,
headers: [
"content-type": "application/x-www-form-urlencoded"
]
)
opts =
Keyword.merge(
Application.get_env(:codebattle, :auth_req_options, []),
form: %{
client_id: client_id(),
client_secret: client_secret(),
grant_type: "authorization_code",
code: code,
redirect_uri: redirect_uri
}
)

@discord_token_url
|> Req.post!(opts)
|> Map.get(:body)
|> URI.decode_query()
|> check_authenticated
|> check_authenticated()
end

defp check_authenticated(%{"access_token" => access_token}) do
Expand All @@ -78,21 +72,24 @@ defmodule Codebattle.Auth.Discord do
defp check_authenticated(error), do: {:error, error}

defp get_user_details(access_token) do
http_client().get!("https://discord.com/api/users/@me",
headers: [
"user-agent": "Codebattle",
authorization: "Bearer #{access_token}"
]
)
opts =
Keyword.merge(
Application.get_env(:codebattle, :auth_req_options, []),
headers: [
"user-agent": "Codebattle",
authorization: "Bearer #{access_token}"
]
)

@discord_user_url
|> Req.get!(opts)
|> Map.get(:body)
|> set_user_details()
end

defp set_user_details({:ok, profile}) do
defp set_user_details(profile) do
atom_key_map = for {key, val} <- profile, into: %{}, do: {String.to_atom(key), val}

{:ok, atom_key_map}
end

defp set_user_details({:error, reason}), do: {:error, reason}
end
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ defmodule Codebattle.Auth.DiscordMock do
],
_options
) do
%{body: Jason.encode!(@body_email_nil)}
%{body: @body_email_nil}
end

def get!("https://discord.com/api/users/@me", _headers, _options) do
%{body: Jason.encode!(@valid_body)}
%{body: @valid_body}
end

@doc """
Expand All @@ -85,10 +85,10 @@ defmodule Codebattle.Auth.DiscordMock do
_headers,
_options
) do
%{body: Jason.encode!(%{error: "error"})}
%{body: %{error: "error"}}
end

def post!(_url, _body, _headers, _options) do
%{body: Jason.encode!(%{access_token: "asfd"})}
%{body: %{access_token: "asfd"}}
end
end
57 changes: 29 additions & 28 deletions services/app/apps/codebattle/lib/codebattle/auth/github.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@ defmodule Codebattle.Auth.Github do
"""

@github_url "https://github.com/login/oauth/"
@github_auth_url @github_url <> "access_token?"

@http_client Application.compile_env(:codebattle, :github_oauth_client)

@doc """
`http_client/0` injects a TestDouble of Req in Test
"""
def http_client, do: @http_client
@github_auth_url "https://github.com/login/oauth/access_token?"
@github_user_url "https://api.github.com/user"

@doc """
`client_id/0` returns a `String` of the `GITHUB_CLIENT_ID`
Expand Down Expand Up @@ -51,15 +45,21 @@ defmodule Codebattle.Auth.Github do
"""
def github_auth(code) do
query =
URI.encode_query(%{
"client_id" => client_id(),
"client_secret" => client_secret(),
"code" => code
})

http_client().post!(@github_auth_url <> query,
headers: ["content-type": "application/x-www-form-urlencoded"]
)
@github_auth_url <>
URI.encode_query(%{
"client_id" => client_id(),
"client_secret" => client_secret(),
"code" => code
})

opts =
Keyword.merge(
Application.get_env(:codebattle, :auth_req_options, []),
headers: ["content-type": "application/x-www-form-urlencoded"]
)

query
|> Req.post!(opts)
|> Map.get(:body)
|> URI.decode_query()
|> check_authenticated
Expand All @@ -73,28 +73,29 @@ defmodule Codebattle.Auth.Github do
defp check_authenticated(error), do: {:error, error}

defp get_user_details(access_token) do
http_client().get!("https://api.github.com/user",
#  https://developer.github.com/v3/#user-agent-required
headers: [
"user-agent": "Codebattle",
authorization: "token #{access_token}"
]
)
opts =
Keyword.merge(
Application.get_env(:codebattle, :auth_req_options, []),
headers: [
"user-agent": "Codebattle",
authorization: "token #{access_token}"
]
)

@github_user_url
|> Req.get!(opts)
|> Map.get(:body)
# |> Jason.decode!()
|> set_user_details(access_token)
end

defp get_primary_email(access_token) do
http_client().get!("https://api.github.com/user/emails",
#  https://developer.github.com/v3/#user-agent-required
Req.get!("https://api.github.com/user/emails",
headers: [
"user-agent": "Codebattle",
authorization: "token #{access_token}"
]
)
|> Map.get(:body)
# |> Jason.decode!()
|> Enum.find_value(&if &1["primary"], do: &1["email"])
end

Expand Down
58 changes: 15 additions & 43 deletions services/app/apps/codebattle/lib/codebattle/auth/github_mock.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ defmodule Codebattle.Auth.GithubMock do
`get/3` stubs the Req get! function when parameters match test vars.
"""
@valid_body %{
access_token: "12345",
login: "test_user",
name: "Testy McTestface",
email: "[email protected]",
avatar_url: "https://avatars3.githubusercontent.com/u/10835816",
id: "19"
"access_token" => "12345",
"login" => "test_user",
"name" => "Testy McTestface",
"email" => "[email protected]",
"avatar_url" => "https://avatars3.githubusercontent.com/u/10835816",
"id" => "19"
}

@body_email_nil %{
access_token: "12345",
login: "test_user",
name: "Testy McTestface",
email: nil,
avatar_url: "https://avatars3.githubusercontent.com/u/10835816",
id: "28"
"access_token" => "12345",
"login" => "test_user",
"name" => "Testy McTestface",
"email" => nil,
"avatar_url" => "https://avatars3.githubusercontent.com/u/10835816",
"id" => "28"
}

@emails [
Expand Down Expand Up @@ -64,7 +64,7 @@ defmodule Codebattle.Auth.GithubMock do
],
_options
) do
%{body: Jason.encode!(@body_email_nil)}
%{body: @body_email_nil}
end

# user emails
Expand All @@ -76,46 +76,18 @@ defmodule Codebattle.Auth.GithubMock do
],
_options
) do
%{body: Jason.encode!(@emails)}
%{body: @emails}
end

def get!(_url, _headers, _options) do
%{body: Jason.encode!(@valid_body)}
%{body: @valid_body}
end

@doc """
`post/3` stubs the Req post! function when parameters match test vars.
"""
def post!(url, body, headers \\ [], options \\ [])

def post!(
"https://github.com/login/oauth/access_token?client_id=TEST_ID&client_secret=TEST_SECRET&code=1234",
_body,
_headers,
_options
) do
%{body: "error=error"}
end

def post!(
"https://github.com/login/oauth/access_token?client_id=TEST_ID&client_secret=TEST_SECRET&code=123",
_body,
_headers,
_options
) do
%{body: "access_token=123"}
end

def post!(
"https://github.com/login/oauth/access_token?client_id=TEST_ID&client_secret=TEST_SECRET&code=42",
_body,
_headers,
_options
) do
%{body: "access_token=42"}
end

# for some reason GitHub's Post returns a URI encoded string
def post!(_url, _body, _headers, _options) do
%{body: URI.encode_query(@valid_body)}
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ defmodule Codebattle.TasksImporter do
File.mkdir_p!(@tmp_basedir)
dir_path = Temp.mkdir!(%{basedir: @tmp_basedir, prefix: to_string(:rand.uniform(10_000_000))})

response = Req.get!(@issues_link) |> dbg()
response = Req.get!(@issues_link)

file_name = Path.join(dir_path, "issues.tar.gz")
File.write!(file_name, response.body)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,10 @@ defmodule CodebattleWeb.AuthController do

case provider_name do
"github" ->
# TODO: user with
{:ok, profile} = Codebattle.Auth.Github.github_auth(code)
Codebattle.Auth.User.GithubUser.find_or_create(profile)

"discord" ->
# TODO: user with
redirect_uri = Routes.auth_url(conn, :callback, provider_name)
{:ok, profile} = Codebattle.Auth.Discord.discord_auth(code, redirect_uri)
Codebattle.Auth.User.DiscordUser.find_or_create(profile)
Expand Down
Loading

0 comments on commit 3856424

Please sign in to comment.