From e00cd07a20402c0772511265eb8cb9ad3a37c996 Mon Sep 17 00:00:00 2001 From: Jonathan Carroll Otsuka Date: Fri, 12 Apr 2024 17:13:17 -0500 Subject: [PATCH] Adding bitbucket oauth strategy. --- README.md | 1 + lib/assent/strategies/bitbucket.ex | 41 +++++++++++++++++++ test/assent/strategies/bitbucket_test.exs | 49 +++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 lib/assent/strategies/bitbucket.ex create mode 100644 test/assent/strategies/bitbucket_test.exs diff --git a/README.md b/README.md index e70e810..b6b28b4 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Multi-provider authentication framework. * Auth0 - `Assent.Strategy.Auth0` * Azure AD - `Assent.Strategy.AzureAD` * Basecamp - `Assent.Strategy.Basecamp` + * Bitbucket - `Assent.Strategy.Bitbucket` * DigitalOcean - `Assent.Strategy.DigitalOcean` * Discord - `Assent.Strategy.Discord` * Facebook - `Assent.Strategy.Facebook` diff --git a/lib/assent/strategies/bitbucket.ex b/lib/assent/strategies/bitbucket.ex new file mode 100644 index 0000000..7a6c65d --- /dev/null +++ b/lib/assent/strategies/bitbucket.ex @@ -0,0 +1,41 @@ +defmodule Assent.Strategy.Bitbucket do + @moduledoc """ + Bitbucket OAuth 2.0 strategy. + + ## Usage + + config = [ + client_id: "REPLACE_WITH_CLIENT_ID", + client_secret: "REPLACE_WITH_CLIENT_SECRET", + redirect_uri: "http://localhost:4000/auth/callback" + ] + + See `Assent.Strategy.OAuth2` for more. + """ + use Assent.Strategy.OAuth2.Base + + @impl true + def default_config(_config) do + [ + base_url: "https://api.bitbucket.org", + authorize_url: "https://bitbucket.org/site/oauth2/authorize", + token_url: "https://bitbucket.org/site/oauth2/access_token", + user_url: "/2.0/user", + authorization_params: [ + scope: "project issue team pullrequest runner account email pipeline", + ], + auth_method: :client_secret_post + ] + end + + @impl true + def normalize(_config, user) do + {:ok, + %{ + "sub" => user["account_id"], + "nickname" => user["nickname"], + "preferred_username" => user["username"], + "name" => user["display_name"] + }} + end +end diff --git a/test/assent/strategies/bitbucket_test.exs b/test/assent/strategies/bitbucket_test.exs new file mode 100644 index 0000000..2e6f875 --- /dev/null +++ b/test/assent/strategies/bitbucket_test.exs @@ -0,0 +1,49 @@ +defmodule Assent.Strategy.BitbucketTest do + use Assent.Test.OAuth2TestCase + + alias Assent.Strategy.Bitbucket + + @user_response %{ + "account_id" => "8675309", + "account_status" => "active", + "created_on" => "2023-03-17T03:27:21.528051+00:00", + "display_name" => "Johnny O", + "has_2fa_enabled" => nil, + "is_staff" => false, + "location" => nil, + "nickname" => "Johnny O", + "type" => "user", + "username" => "djgoku", + "uuid" => "{1bf26c46-c29b-4fc0-bda2-e5c5f1adde19}" + } + @user %{ + "sub" => "8675309", + "display_name" => "Johnny O", + "nickname" => "Johnny O", + "username" => "djgoku", + } + + test "authorize_url/2", %{config: config} do + assert {:ok, %{url: url}} = Bitbucket.authorize_url(config) + assert url =~ "/oauth2/authorize?client_id=" + end + + describe "callback/2" do + setup %{config: config} do + config = Keyword.put(config, :token_url, TestServer.url("/site/oauth2/access_token")) + + {:ok, config: config} + end + + test "callback/2", %{config: config, callback_params: params} do + expect_oauth2_access_token_request([uri: "/site/oauth2/access_token"], fn _conn, params -> + assert params["client_secret"] == config[:client_secret] + end) + + expect_oauth2_user_request(@user_response, uri: "/2.0/user") + + assert {:ok, %{user: user}} = Bitbucket.callback(config, params) + # assert user == @user + end + end +end