This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch issue/oauth-oidc-spotify
in repository https://gitbox.apache.org/repos/asf/sling-samples.git

commit d12e767ebbb607d4b60af9e0dc3218bf48309dec
Author: Robert Munteanu <romb...@apache.org>
AuthorDate: Mon Sep 1 17:11:01 2025 +0200

    feat(oauth): login with Spotify
---
 oauth/README.md                                    | 11 ++++++++++
 oauth/launcher/Makefile                            |  7 +++++++
 oauth/launcher/src/main/features/launcher.json     | 21 ++++++++++++++++++-
 .../components/spotify-playlists/.content.xml      | 22 ++++++++++++++++++++
 .../spotify-playlists/spotify-playlists.html       | 19 +++++++++++++++++
 .../oauth-demo/components/welcome/welcome.html     |  7 +++++--
 .../content/oauth-demo/playlists/.content.xml      | 24 ++++++++++++++++++++++
 7 files changed, 108 insertions(+), 3 deletions(-)

diff --git a/oauth/README.md b/oauth/README.md
index 23414d2..4c1c52c 100644
--- a/oauth/README.md
+++ b/oauth/README.md
@@ -54,6 +54,17 @@ Obtain the client id and client secret and save them under
 - `launcher/secrets/github/clientId`
 - `launcher/secrets/github/clientSecret`
 
+### Spotify
+
+Create a new Spotify Developer app and generate client credentials for it. 
Follow the documentation from
+https://developer.spotify.com/documentation/web-api . No special permissions 
are needed.
+
+Obtain the client id and client secret and save them under
+
+- `launcher/secrets/spotify/clientId`
+- `launcher/secrets/spotify/clientSecret`
+
+
 ## Launching
 
 Change to the launcher directory and run `make run`.  This will check if the 
required secrets are
diff --git a/oauth/launcher/Makefile b/oauth/launcher/Makefile
index eb1f716..633765b 100644
--- a/oauth/launcher/Makefile
+++ b/oauth/launcher/Makefile
@@ -28,6 +28,13 @@ secrets/github/clientId:
 secrets/github/clientSecret:
        @echo [WARN] $@ missing, OAuth config needs to be created manually
 
+secrets/spotify/clientId:
+       @echo [WARN] $@ missing, OIDC config needs to be created manually
+
+secrets/spotify/clientSecret:
+       @echo [WARN] $@ missing, OIDC config needs to be created manually
+
+
 secrets/encrypt/password:
        mkdir -p secrets/encrypt
        openssl rand  -hex 32 > $@
diff --git a/oauth/launcher/src/main/features/launcher.json 
b/oauth/launcher/src/main/features/launcher.json
index a201ec6..bdb7215 100644
--- a/oauth/launcher/src/main/features/launcher.json
+++ b/oauth/launcher/src/main/features/launcher.json
@@ -27,8 +27,27 @@
         "clientSecret": "$[secret:github/clientSecret]",
         "scopes": ["openid", "user:email"],
         "additionalAuthorizationParameters": ["prompt=select_account"]
+   },
+   "org.apache.sling.auth.oauth_client.impl.OidcConnectionImpl~spotify": {
+        "name": "spotify",
+        "baseUrl": "https://accounts.spotify.com";,
+        "clientId": "$[secret:spotify/clientId]",
+        "clientSecret": "$[secret:spotify/clientSecret]",
+        "scopes": ["openid"]
     },
-    "org.apache.sling.auth.oauth_client.impl.JcrUserHomeOAuthTokenStore" : {
+    "org.apache.sling.auth.oauth_client.impl.OidcAuthenticationHandler": {
+        "path": "/content/oauth-demo/playlists",
+        "defaultConnectionName": "spotify",
+        "idp": "spotify-idp"
+    },
+    
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler~spotify":
 {
+        "handler.name": "handler-spotify"
+    },
+    
"org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory~spotify":
 {
+        "idp.name": "spotify-idp",
+        "sync.handlerName": "handler-spotify"
+    },
+    "org.apache.sling.auth.oauth_client.impl.JcrUserHomeOAuthTokenStore": {
     },
     "org.apache.sling.commons.crypto.internal.FilePasswordProvider~oauth": {
         "path": "secrets/encrypt/password",
diff --git 
a/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/spotify-playlists/.content.xml
 
b/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/spotify-playlists/.content.xml
new file mode 100644
index 0000000..20e138a
--- /dev/null
+++ 
b/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/spotify-playlists/.content.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"; 
xmlns:jcr="http://www.jcp.org/jcr/1.0";
+          jcr:primaryType="sling:Folder"
+/>
diff --git 
a/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/spotify-playlists/spotify-playlists.html
 
b/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/spotify-playlists/spotify-playlists.html
new file mode 100644
index 0000000..0bbb6ea
--- /dev/null
+++ 
b/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/spotify-playlists/spotify-playlists.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <link href="/oauth-demo/static/css/output.css" rel="stylesheet">
+  <link rel="icon" href="/oauth-demo/static/favicon.ico">
+  <title>Spotify Playlists</title>
+</head>
+<body 
data-sly-use.youtube="org.apache.sling.samples.oauth_demo.YoutubeVideosModel">
+    <main>
+        <header class="flex flex-row justify-between">
+            <h1>Spotify Playlists</h1>
+        </header>
+        <p>Not implemented.</p>
+        <p>Back to the <a class="underline" href="../oauth-demo.html">main 
page</a>.</p>
+    </main>
+</body>
+</html>
\ No newline at end of file
diff --git 
a/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/welcome/welcome.html
 
b/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/welcome/welcome.html
index d99b597..4636a05 100644
--- 
a/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/welcome/welcome.html
+++ 
b/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/welcome/welcome.html
@@ -17,17 +17,19 @@
                 <p>If you prefer, you can <a 
href="/system/sling/logout.html?resource=${resource.path}.html" 
class="underline">log out</a>.</p>
             </div>
             <div data-sly-test="${!user.loggedIn}">
-                <p>Please <a 
href="/system/sling/login.html?resource=${resource.path}.html" 
class="underline">log in</a> to access the demo pages.</p>
+                <p>Access the <a class="underline" 
href="oauth-demo/playlists.html">Spotify playlists</a> page.</p>
+                <p>Please <a 
href="/system/sling/login.html?resource=${resource.path}.html" 
class="underline">log in</a> to access the other demo pages.</p>
             </div>
         </sly>
         
         <h2>About the demo</h2>
         <p>This application shows the expected basic usage of the <a 
class="underline" 
href="https://github.com/apache/sling-org-apache-sling-auth-oauth-client";>Sling 
OAuth Client bundle</a></em></p>
         
-        <p>It exposes two pages:
+        <p>It exposes three pages:
             <ul class="list-disc list-inside">
                 <li>The Youtube videos page ( <a class="underline" 
href="https://github.com/apache/sling-samples/tree/master/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/youtube-videos";>oauth-demo/components/youtube-videos</a>),
 implemented using a Sling Servlet ( <a class="underline" 
href="https://github.com/apache/sling-samples/blob/master/oauth/core/src/main/java/org/apache/sling/samples/oauth_demo/impl/YoutubeSearchServlet.java";>YoutubeSearchServlet</a>)
 </li>
                 <li>The GitHub repositories page ( <a class="underline" 
href="https://github.com/apache/sling-samples/tree/master/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/github-repos";>oauth-demo/components/github-repos</a>),
 backed by a Sling Model ( <a class="underline" 
href="https://github.com/apache/sling-samples/blob/master/oauth/core/src/main/java/org/apache/sling/samples/oauth_demo/GithubRepositoriesModel.java";>GithubRepositoriesModel</a>)
 </li>
+                <li>The Spotify playlists page ( <a class="underline" 
href="https://github.com/apache/sling-samples/tree/master/oauth/ui.apps/src/main/content/jcr_root/apps/oauth-demo/components/spotify-playlists";>oauth-demo/components/spotify-playlists</a>),
 implemented using a TODO</li>
             </ul>
         </p>
         
@@ -35,6 +37,7 @@
             <ul class="list-disc list-inside">
                 <li>Google: <a target="_blank" class="underline" 
href="https://developers.google.com/identity/protocols/oauth2";>Using OAuth 2.0 
to Access Google APIs </a></li>
                 <li>GitHub: <a target="_blank" class="underline" 
href="https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps";>Authorizing
 OAuth Apps</a></li>
+                <li>Spotify: <a target="_blank" class="underline" 
href="https://developer.spotify.com/documentation/web-api/tutorials/getting-started";>Getting
 started with Web API</a></li>
             </ul>
         </p>
        
diff --git 
a/oauth/ui.apps/src/main/content/jcr_root/content/oauth-demo/playlists/.content.xml
 
b/oauth/ui.apps/src/main/content/jcr_root/content/oauth-demo/playlists/.content.xml
new file mode 100644
index 0000000..fc54601
--- /dev/null
+++ 
b/oauth/ui.apps/src/main/content/jcr_root/content/oauth-demo/playlists/.content.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"; 
xmlns:nt="http://www.jcp.org/jcr/nt/1.0";
+          xmlns:sling="http://sling.apache.org/jcr/sling/1.0";
+          jcr:primaryType="sling:Folder"
+          sling:resourceType="oauth-demo/components/spotify-playlists"
+/>
\ No newline at end of file

Reply via email to