From 1feb57ef22de0f204e45a5068df4e5dc4990605e Mon Sep 17 00:00:00 2001 From: emera Date: Thu, 21 Nov 2024 17:21:45 +0200 Subject: [PATCH] OAuth for Apple account --- README.md | 1 + .../scribejava/apis/apple/AppleIDApi.java | 60 ++++++++++++++++ .../scribejava/apis/apple/AppleIDService.java | 27 +++++++ .../apis/examples/AppleIDExample.java | 72 +++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDApi.java create mode 100644 scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDService.java create mode 100644 scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AppleIDExample.java diff --git a/README.md b/README.md index b90ef2e5f..08f9b223a 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ ScribeJava support out-of-box several HTTP clients: ### Supports all (50+) major 1.0a and 2.0 OAuth APIs out-of-the-box +* Apple (https://account.apple.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AppleIDExample.java) * Asana (https://asana.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AsanaExample.java) * Automatic (https://www.automatic.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AutomaticExample.java) * AWeber (http://www.aweber.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AWeberExample.java) diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDApi.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDApi.java new file mode 100644 index 000000000..1c1e84923 --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDApi.java @@ -0,0 +1,60 @@ +package com.github.scribejava.apis.apple; + +import java.io.OutputStream; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; +import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication; +import com.github.scribejava.core.oauth2.clientauthentication.RequestBodyAuthenticationScheme; + +public class AppleIDApi extends DefaultApi20 +{ + + protected AppleIDApi() + { + } + + private static class InstanceHolder + { + private static final AppleIDApi INSTANCE = new AppleIDApi(); + } + + public static AppleIDApi instance() + { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() + { + return "https://appleid.apple.com/auth/token"; + } + + @Override + protected String getAuthorizationBaseUrl() + { + return "https://appleid.apple.com/auth/authorize"; + } + + @Override + public String getRevokeTokenEndpoint() + { + return "https://appleid.apple.com/auth/revoke"; + } + + @Override + public ClientAuthentication getClientAuthentication() + { + return RequestBodyAuthenticationScheme.instance(); + } + + @Override + public AppleIDService createService(String apiKey, String apiSecret, String callback, String defaultScope, + String responseType, OutputStream debugStream, String userAgent, HttpClientConfig httpClientConfig, + HttpClient httpClient) + { + return new AppleIDService(this, apiKey, apiSecret, callback, defaultScope, responseType, debugStream, + userAgent, httpClientConfig, httpClient); + } +} diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDService.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDService.java new file mode 100644 index 000000000..6072ea9ac --- /dev/null +++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/apple/AppleIDService.java @@ -0,0 +1,27 @@ +package com.github.scribejava.apis.apple; + +import java.io.OutputStream; + +import com.github.scribejava.core.builder.api.DefaultApi20; +import com.github.scribejava.core.httpclient.HttpClient; +import com.github.scribejava.core.httpclient.HttpClientConfig; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.oauth.AccessTokenRequestParams; +import com.github.scribejava.core.oauth.OAuth20Service; + +public class AppleIDService extends OAuth20Service +{ + public AppleIDService(DefaultApi20 api, String apiKey, String apiSecret, String callback, String defaultScope, String responseType, + OutputStream debugStream, String userAgent, HttpClientConfig httpClientConfig, HttpClient httpClient) + { + super(api, apiKey, apiSecret, callback, defaultScope, responseType, debugStream, userAgent, httpClientConfig, httpClient); + } + + @Override + protected OAuthRequest createAccessTokenRequest(AccessTokenRequestParams params) + { + OAuthRequest req = super.createAccessTokenRequest(params); + req.addHeader("Content-Type", "application/x-www-form-urlencoded"); + return req; + } +} diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AppleIDExample.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AppleIDExample.java new file mode 100644 index 000000000..c13db7c47 --- /dev/null +++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AppleIDExample.java @@ -0,0 +1,72 @@ +package com.github.scribejava.apis.examples; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.Scanner; + +import com.github.scribejava.apis.apple.AppleIDApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthConstants; +import com.github.scribejava.core.oauth.OAuth20Service; + +public class AppleIDExample { + + public static void main(String[] args) throws Exception { + final String apiKey = "your client id"; + final String apiSecret = "your client secret"; + final String secretState = "secret" + new Random().nextInt(999_999); + + OAuth20Service service = new ServiceBuilder(apiKey) + .apiSecret(apiSecret) + .callback("https://localhost/") + .defaultScope("name email") + .responseType("code id_token") + .build(AppleIDApi.instance()); + + Map additionalParams = new HashMap<>(); + additionalParams.put(OAuthConstants.STATE, secretState); + additionalParams.put("response_mode", "form_post"); + + try (Scanner in = new Scanner(System.in)) { + System.out.println("Fetching the Authorication URL..."); + System.out.println("Got the Authorization URL!"); + final String authorizationUrl = service.getAuthorizationUrl(additionalParams); + System.out.println("Now go and authorize ScribeJava here:"); + System.out.println(authorizationUrl); + System.out.println("And paste the authorization code here"); + System.out.print(">>"); + final String code = in.nextLine(); + System.out.println(); + + System.out.println("Trading the Authorization Code for an Access Token..."); + OAuth2AccessToken accessToken = service.getAccessToken(code); + System.out.println("Got the Access Token!"); + System.out.println("(The raw response looks like this: " + accessToken.getRawResponse() + "')"); + System.out.println(); + + System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'."); + System.out.print(">>"); + final String value = in.nextLine(); + if (secretState.equals(value)) { + System.out.println("State value does match!"); + } else { + System.out.println("Ooops, state value does not match!"); + System.out.println("Expected = " + secretState); + System.out.println("Got = " + value); + System.out.println(); + } + + System.out.println("Refreshing the Access Token..."); + accessToken = service.refreshAccessToken(accessToken.getRefreshToken()); + System.out.println("Refreshed the Access Token!"); + System.out.println("(The raw response looks like this: " + accessToken.getRawResponse() + "')"); + } + + System.out.println(); + + System.out.println(); + System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)"); + } +}