From e5875c5dc68409909a8c43e343f9fdcfe65021d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mielcarek?= Date: Mon, 7 Nov 2022 23:15:41 +0100 Subject: [PATCH] =?UTF-8?q?Impl=C3=A9mentation=20refresh=20token=20et=20cl?= =?UTF-8?q?ean=20up=20du=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/dafl_project_flutter/lib/api/api.dart | 121 ++++++++++++------ .../lib/api/in_app_browser.dart | 3 +- .../flutter/generated_plugin_registrant.cc | 11 ++ .../flutter/generated_plugin_registrant.h | 15 +++ .../linux/flutter/generated_plugins.cmake | 23 ++++ 5 files changed, 130 insertions(+), 43 deletions(-) create mode 100644 Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.cc create mode 100644 Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.h create mode 100644 Sources/dafl_project_flutter/linux/flutter/generated_plugins.cmake diff --git a/Sources/dafl_project_flutter/lib/api/api.dart b/Sources/dafl_project_flutter/lib/api/api.dart index c89ff72..d7d824d 100644 --- a/Sources/dafl_project_flutter/lib/api/api.dart +++ b/Sources/dafl_project_flutter/lib/api/api.dart @@ -3,73 +3,110 @@ import 'dart:math'; import 'package:http/http.dart' as http; class Api { - var clientId = '7ceb49d874b9404492246027e4d68cf8'; - var clientSecret = '98f9cb960bf54ebbb9ad306e7ff919cb'; - var redirectUri = 'https://daflmusic.000webhostapp.com/callback/'; - var state; - String scopes = 'user-read-playback-state user-read-currently-playing'; - var code; - var urlAuthorize; - String? access_token; - String token_type = 'Bearer '; - int? expires_in; - String? refresh_token; + //from dashboard + final _clientId = '7ceb49d874b9404492246027e4d68cf8'; + final _clientSecret = '98f9cb960bf54ebbb9ad306e7ff919cb'; // TODO : hide it - var client = http.Client(); + //for web api + get redirectUri => 'https://daflmusic.000webhostapp.com/callback/'; + final _scopes = 'user-read-playback-state user-read-currently-playing'; + String? _state; + String? _encodedLogs; + final _tokenType = 'Bearer '; + + //from web api + String? _code; + int? _expiresIn; + String? _refreshToken; + String? _accessToken; //use _getToken() as kind of a private getter + + //other + final _client = http.Client(); + Uri? _urlAuthorize; + get urlAuthorize => _urlAuthorize; + DateTime? _tokenEnd; Api() { - state = generateRandomString(); - urlAuthorize = Uri.https('accounts.spotify.com', 'authorize', { - 'client_id': clientId, + _state = _generateRandomString(); + _encodedLogs = base64.encode(utf8.encode("$_clientId:$_clientSecret")); + _urlAuthorize = Uri.https('accounts.spotify.com', 'authorize', { + 'client_id': _clientId, 'response_type': 'code', 'redirect_uri': redirectUri, - 'state': state, - 'scope': scopes, + 'state': _state, + 'scope': _scopes, 'show_dialog': 'true' }); } - requestUserAuthorization(Uri url) { - if (url.queryParameters['state'] == state.toString()) { - code = url.queryParameters['code']; - requestAccessToken(); + // for state value + String _generateRandomString() { + var r = Random(); + return String.fromCharCodes( + List.generate(16, (index) => r.nextInt(33) + 89)); + } + + //session management + + requestUserAuthorization(Uri url) async { + if (url.queryParameters['state'] == _state.toString()) { + _code = url.queryParameters['code']; + await _requestAccessToken(); } // TODO : implement the else } - requestAccessToken() async { + _requestAccessToken() async { var urlToken = Uri.https('accounts.spotify.com', 'api/token', { - 'code': code, + 'code': _code, 'redirect_uri': redirectUri, 'grant_type': 'authorization_code' }); - String credentials = "$clientId:$clientSecret"; - String encodedLogs = base64.encode(utf8.encode(credentials)); - var response = await client.post(urlToken, headers: { - 'Authorization': 'Basic $encodedLogs', + var response = await _client.post(urlToken, headers: { + 'Authorization': 'Basic $_encodedLogs', + 'Content-Type': 'application/x-www-form-urlencoded' + }); + var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map; + _accessToken = decodedResponse['access_token']; + _expiresIn = decodedResponse['expires_in']; + _tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!)); + _refreshToken = decodedResponse['refresh_token']; + } + + Future _getToken() async { + await _tokenValidity(); + return _accessToken; + } + + _tokenValidity() async { + if (DateTime.now().isAfter(_tokenEnd!)) { + await _getRefreshedAccessToken(); + } + } + + _getRefreshedAccessToken() async { + var urlToken = Uri.https('accounts.spotify.com', 'api/token', + {'grant_type': 'refresh_token', 'refresh_token': '$_refreshToken'}); + var response = await _client.post(urlToken, headers: { + 'Authorization': 'Basic $_encodedLogs', 'Content-Type': 'application/x-www-form-urlencoded' }); var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map; - access_token = decodedResponse['access_token']; - expires_in = decodedResponse['expires_in']; - refresh_token = decodedResponse['refresh_token']; - getCurrentlyPlayingTrack(); + _accessToken = decodedResponse['access_token']; + _expiresIn = decodedResponse['expires_in']; + _tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!)); } + //functional methods + getCurrentlyPlayingTrack() async { var url = Uri.https('api.spotify.com', 'v1/me/player/currently-playing'); - var response = await client.get(url, headers: { - 'Authorization': '$token_type $access_token', + var token = await _getToken(); + var response = await _client.get(url, headers: { + 'Authorization': '$_tokenType $token', 'Content-Type': 'application/json' }); - // Implement traitement of datas - print(response.body); - } - - // for state value - String generateRandomString() { - var r = Random(); - return String.fromCharCodes( - List.generate(16, (index) => r.nextInt(33) + 89)); + // Implement treatment of data's + //print(response.body); } } diff --git a/Sources/dafl_project_flutter/lib/api/in_app_browser.dart b/Sources/dafl_project_flutter/lib/api/in_app_browser.dart index 0a84200..1670995 100644 --- a/Sources/dafl_project_flutter/lib/api/in_app_browser.dart +++ b/Sources/dafl_project_flutter/lib/api/in_app_browser.dart @@ -24,7 +24,8 @@ class MyInAppBrowser extends InAppBrowser { @override Future onLoadStart(url) async { if (url!.origin + url.path == MyApp.api.redirectUri) { - MyApp.api.requestUserAuthorization(url); + await MyApp.api.requestUserAuthorization(url); + await MyApp.api.getCurrentlyPlayingTrack(); close(); } } diff --git a/Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.cc b/Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..e71a16d --- /dev/null +++ b/Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.h b/Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..e0f0a47 --- /dev/null +++ b/Sources/dafl_project_flutter/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/Sources/dafl_project_flutter/linux/flutter/generated_plugins.cmake b/Sources/dafl_project_flutter/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000..2e1de87 --- /dev/null +++ b/Sources/dafl_project_flutter/linux/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin)