Skip to content

Commit 5b16f73

Browse files
authored
Merge pull request #132 from sondr3/spotify-strategy
Create Spotify strategy
2 parents d376abe + 88aaa13 commit 5b16f73

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v0.2.5 (TBA)
4+
5+
* `Assent.Strategy.Spotify` added
6+
37
## v0.2.4 (2023-08-20)
48

59
* Fixed bug in `Assent.JWTAdapter.AssentJWT` where `verified?` could be a `{:error, term()}` tuple rather than boolean

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Multi-provider authentication framework.
2626
* Instagram - `Assent.Strategy.Instagram`
2727
* LINE Login - `Assent.Strategy.LINE`
2828
* Linkedin - `Assent.Strategy.Linkedin`
29+
* Spotify - `Assent.Strategy.Spoty`
2930
* Slack - `Assent.Strategy.Slack`
3031
* Stripe Connect - `Assent.Strategy.Stripe`
3132
* Twitter - `Assent.Strategy.Twitter`

lib/assent/strategies/spotify.ex

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
defmodule Assent.Strategy.Spotify do
2+
@moduledoc """
3+
Spotify OAuth 2.0 strategy.
4+
5+
## Usage
6+
7+
config = [
8+
client_id: "REPLACE_WITH_CLIENT_ID",
9+
client_secret: "REPLACE_WITH_CLIENT_SECRET"
10+
]
11+
12+
See `Assent.Strategy.OAuth2` for more.
13+
"""
14+
use Assent.Strategy.OAuth2.Base
15+
16+
@impl true
17+
def default_config(_config) do
18+
[
19+
site: "https://api.spotify.com/v1",
20+
authorize_url: "https://accounts.spotify.com/authorize",
21+
token_url: "https://accounts.spotify.com/api/token",
22+
user_url: "/me",
23+
authorization_params: [scope: "user-read-email"],
24+
auth_method: :client_secret_post
25+
]
26+
end
27+
28+
@impl true
29+
def normalize(_config, user) do
30+
{:ok,
31+
%{
32+
"sub" => user["id"],
33+
"name" => user["display_name"],
34+
"preferred_username" => user["display_name"],
35+
"email" => user["email"],
36+
"picture" => picture_url(user)
37+
}}
38+
end
39+
40+
defp picture_url(user) do
41+
List.first(user["images"])["url"]
42+
end
43+
end
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
defmodule Assent.Strategy.SpotifyTest do
2+
use Assent.Test.OAuth2TestCase
3+
4+
alias Assent.Strategy.Spotify
5+
6+
# From https://developer.spotify.com/documentation/web-api/reference/get-current-users-profile
7+
# but with some test data added
8+
@user_response %{
9+
"display_name" => "nick",
10+
"email" => "[email protected]",
11+
"external_urls" => %{"spotify" => "https://open.spotify.com/user/username"},
12+
"followers" => %{"href" => nil, "total" => 1},
13+
"href" => "https://api.spotify.com/v1/users/username",
14+
"id" => "username",
15+
"images" => [
16+
%{
17+
"height" => 64,
18+
"url" => "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
19+
"width" => 64
20+
},
21+
%{
22+
"height" => 300,
23+
"url" => "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
24+
"width" => 300
25+
}
26+
],
27+
"type" => "user",
28+
"uri" => "spotify:user:username"
29+
}
30+
@user %{
31+
"sub" => "username",
32+
"email" => "[email protected]",
33+
"picture" => "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
34+
"preferred_username" => "nick",
35+
"name" => "nick"
36+
}
37+
38+
test "authorize_url/2", %{config: config} do
39+
assert {:ok, %{url: url}} = Spotify.authorize_url(config)
40+
assert url =~ "https://accounts.spotify.com/authorize?client_id="
41+
end
42+
43+
describe "callback/2" do
44+
setup %{config: config} do
45+
config = Keyword.put(config, :token_url, TestServer.url("/api/token"))
46+
47+
{:ok, config: config}
48+
end
49+
50+
test "callback/2", %{config: config, callback_params: params} do
51+
expect_oauth2_access_token_request([uri: "/api/token"], fn _conn, params ->
52+
assert params["client_secret"] == config[:client_secret]
53+
end)
54+
55+
expect_oauth2_user_request(@user_response, uri: "/me")
56+
57+
assert {:ok, %{user: user}} = Spotify.callback(config, params)
58+
assert user == @user
59+
end
60+
end
61+
end

0 commit comments

Comments
 (0)