Skip to content

Commit

Permalink
Merge pull request #132 from sondr3/spotify-strategy
Browse files Browse the repository at this point in the history
Create Spotify strategy
  • Loading branch information
danschultzer committed Aug 22, 2023
2 parents d376abe + 88aaa13 commit 5b16f73
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.2.5 (TBA)

* `Assent.Strategy.Spotify` added

## v0.2.4 (2023-08-20)

* Fixed bug in `Assent.JWTAdapter.AssentJWT` where `verified?` could be a `{:error, term()}` tuple rather than boolean
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Multi-provider authentication framework.
* Instagram - `Assent.Strategy.Instagram`
* LINE Login - `Assent.Strategy.LINE`
* Linkedin - `Assent.Strategy.Linkedin`
* Spotify - `Assent.Strategy.Spoty`
* Slack - `Assent.Strategy.Slack`
* Stripe Connect - `Assent.Strategy.Stripe`
* Twitter - `Assent.Strategy.Twitter`
Expand Down
43 changes: 43 additions & 0 deletions lib/assent/strategies/spotify.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
defmodule Assent.Strategy.Spotify do
@moduledoc """
Spotify OAuth 2.0 strategy.
## Usage
config = [
client_id: "REPLACE_WITH_CLIENT_ID",
client_secret: "REPLACE_WITH_CLIENT_SECRET"
]
See `Assent.Strategy.OAuth2` for more.
"""
use Assent.Strategy.OAuth2.Base

@impl true
def default_config(_config) do
[
site: "https://api.spotify.com/v1",
authorize_url: "https://accounts.spotify.com/authorize",
token_url: "https://accounts.spotify.com/api/token",
user_url: "/me",
authorization_params: [scope: "user-read-email"],
auth_method: :client_secret_post
]
end

@impl true
def normalize(_config, user) do
{:ok,
%{
"sub" => user["id"],
"name" => user["display_name"],
"preferred_username" => user["display_name"],
"email" => user["email"],
"picture" => picture_url(user)
}}
end

defp picture_url(user) do
List.first(user["images"])["url"]
end
end
61 changes: 61 additions & 0 deletions test/assent/strategies/spotify_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
defmodule Assent.Strategy.SpotifyTest do
use Assent.Test.OAuth2TestCase

alias Assent.Strategy.Spotify

# From https://developer.spotify.com/documentation/web-api/reference/get-current-users-profile
# but with some test data added
@user_response %{
"display_name" => "nick",
"email" => "[email protected]",
"external_urls" => %{"spotify" => "https://open.spotify.com/user/username"},
"followers" => %{"href" => nil, "total" => 1},
"href" => "https://api.spotify.com/v1/users/username",
"id" => "username",
"images" => [
%{
"height" => 64,
"url" => "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
"width" => 64
},
%{
"height" => 300,
"url" => "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
"width" => 300
}
],
"type" => "user",
"uri" => "spotify:user:username"
}
@user %{
"sub" => "username",
"email" => "[email protected]",
"picture" => "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
"preferred_username" => "nick",
"name" => "nick"
}

test "authorize_url/2", %{config: config} do
assert {:ok, %{url: url}} = Spotify.authorize_url(config)
assert url =~ "https://accounts.spotify.com/authorize?client_id="
end

describe "callback/2" do
setup %{config: config} do
config = Keyword.put(config, :token_url, TestServer.url("/api/token"))

{:ok, config: config}
end

test "callback/2", %{config: config, callback_params: params} do
expect_oauth2_access_token_request([uri: "/api/token"], fn _conn, params ->
assert params["client_secret"] == config[:client_secret]
end)

expect_oauth2_user_request(@user_response, uri: "/me")

assert {:ok, %{user: user}} = Spotify.callback(config, params)
assert user == @user
end
end
end

0 comments on commit 5b16f73

Please sign in to comment.