From 2507f3301b0bcd57d1aa810c65def2bc80d4b62e Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 4 Sep 2019 11:52:32 -0400 Subject: [PATCH] device user agent --- src/Android/MainApplication.cs | 5 +++-- src/Android/Services/DeviceActionService.cs | 14 ++++++++++++++ src/App/Abstractions/IDeviceActionService.cs | 1 + src/Core/Services/ApiService.cs | 14 +++++++------- src/Core/Utilities/ServiceContainer.cs | 5 +++-- .../CredentialProviderViewController.cs | 4 +++- src/iOS.Core/Services/DeviceActionService.cs | 16 +++++++++++++++- src/iOS.Extension/LoadingViewController.cs | 8 +++++--- src/iOS/AppDelegate.cs | 3 ++- 9 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/Android/MainApplication.cs b/src/Android/MainApplication.cs index 7d90e7d92..72b04a2aa 100644 --- a/src/Android/MainApplication.cs +++ b/src/Android/MainApplication.cs @@ -40,7 +40,8 @@ namespace Bit.Droid if(ServiceContainer.RegisteredServices.Count == 0) { RegisterLocalServices(); - ServiceContainer.Init(); + var deviceActionService = ServiceContainer.Resolve("deviceActionService"); + ServiceContainer.Init(deviceActionService.DeviceUserAgent); if(App.Migration.MigrationHelpers.NeedsMigration()) { var task = App.Migration.MigrationHelpers.PerformMigrationAsync(); @@ -155,4 +156,4 @@ namespace Bit.Droid await ServiceContainer.Resolve("environmentService").SetUrlsFromStorageAsync(); } } -} \ No newline at end of file +} diff --git a/src/Android/Services/DeviceActionService.cs b/src/Android/Services/DeviceActionService.cs index f07e1b5e5..e08ef81e5 100644 --- a/src/Android/Services/DeviceActionService.cs +++ b/src/Android/Services/DeviceActionService.cs @@ -40,6 +40,7 @@ namespace Bit.Droid.Services private ProgressDialog _progressDialog; private bool _cameraPermissionsDenied; private Toast _toast; + private string _userAgent; public DeviceActionService( IStorageService storageService, @@ -61,6 +62,19 @@ namespace Bit.Droid.Services }); } + public string DeviceUserAgent + { + get + { + if(string.IsNullOrWhiteSpace(_userAgent)) + { + _userAgent = $"Bitwarden_Mobile/{Xamarin.Essentials.AppInfo.VersionString} " + + $"(Android {Build.VERSION.Release}; SDK {Build.VERSION.Sdk}; Model {Build.Model})"; + } + return _userAgent; + } + } + public DeviceType DeviceType => DeviceType.Android; public void Toast(string text, bool longDuration = false) diff --git a/src/App/Abstractions/IDeviceActionService.cs b/src/App/Abstractions/IDeviceActionService.cs index 6f033c7fc..f9e120bcf 100644 --- a/src/App/Abstractions/IDeviceActionService.cs +++ b/src/App/Abstractions/IDeviceActionService.cs @@ -6,6 +6,7 @@ namespace Bit.App.Abstractions { public interface IDeviceActionService { + string DeviceUserAgent { get; } DeviceType DeviceType { get; } void Toast(string text, bool longDuration = false); bool LaunchApp(string appName); diff --git a/src/Core/Services/ApiService.cs b/src/Core/Services/ApiService.cs index 9280b314e..aa887ae86 100644 --- a/src/Core/Services/ApiService.cs +++ b/src/Core/Services/ApiService.cs @@ -25,18 +25,22 @@ namespace Bit.Core.Services private readonly ITokenService _tokenService; private readonly IPlatformUtilsService _platformUtilsService; private readonly Func _logoutCallbackAsync; - private string _deviceType; public ApiService( ITokenService tokenService, IPlatformUtilsService platformUtilsService, - Func logoutCallbackAsync) + Func logoutCallbackAsync, + string customUserAgent = null) { _tokenService = tokenService; _platformUtilsService = platformUtilsService; _logoutCallbackAsync = logoutCallbackAsync; var device = _platformUtilsService.GetDevice(); - _deviceType = device.ToString(); + _httpClient.DefaultRequestHeaders.Add("Device-Type", device.ToString()); + if(!string.IsNullOrWhiteSpace(customUserAgent)) + { + _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(customUserAgent); + } } public bool UrlsSet { get; private set; } @@ -86,7 +90,6 @@ namespace Bit.Core.Services Content = new FormUrlEncodedContent(request.ToIdentityToken(_platformUtilsService.IdentityClientId)) }; requestMessage.Headers.Add("Accept", "application/json"); - requestMessage.Headers.Add("Device-Type", _deviceType); HttpResponseMessage response; try @@ -304,7 +307,6 @@ namespace Bit.Core.Services { requestMessage.Method = HttpMethod.Post; requestMessage.RequestUri = new Uri(string.Concat(EventsBaseUrl, "/collect")); - requestMessage.Headers.Add("Device-Type", _deviceType); var authHeader = await GetActiveBearerTokenAsync(); requestMessage.Headers.Add("Authorization", string.Concat("Bearer ", authHeader)); requestMessage.Content = new StringContent(JsonConvert.SerializeObject(request, _jsonSettings), @@ -377,7 +379,6 @@ namespace Bit.Core.Services } } - requestMessage.Headers.Add("Device-Type", _deviceType); if(authed) { var authHeader = await GetActiveBearerTokenAsync(); @@ -432,7 +433,6 @@ namespace Bit.Core.Services }) }; requestMessage.Headers.Add("Accept", "application/json"); - requestMessage.Headers.Add("Device-Type", _deviceType); HttpResponseMessage response; try diff --git a/src/Core/Utilities/ServiceContainer.cs b/src/Core/Utilities/ServiceContainer.cs index de2d891a9..498646c94 100644 --- a/src/Core/Utilities/ServiceContainer.cs +++ b/src/Core/Utilities/ServiceContainer.cs @@ -11,7 +11,7 @@ namespace Bit.Core.Utilities public static Dictionary RegisteredServices { get; set; } = new Dictionary(); public static bool Inited { get; set; } - public static void Init() + public static void Init(string customUserAgent = null) { if(Inited) { @@ -31,7 +31,8 @@ namespace Bit.Core.Utilities var cryptoFunctionService = new PclCryptoFunctionService(cryptoPrimitiveService); var cryptoService = new CryptoService(storageService, secureStorageService, cryptoFunctionService); var tokenService = new TokenService(storageService); - var apiService = new ApiService(tokenService, platformUtilsService, (bool expired) => Task.FromResult(0)); + var apiService = new ApiService(tokenService, platformUtilsService, (bool expired) => Task.FromResult(0), + customUserAgent); var appIdService = new AppIdService(storageService); var userService = new UserService(storageService, tokenService); var settingsService = new SettingsService(userService, storageService); diff --git a/src/iOS.Autofill/CredentialProviderViewController.cs b/src/iOS.Autofill/CredentialProviderViewController.cs index c7437795e..baebc1a56 100644 --- a/src/iOS.Autofill/CredentialProviderViewController.cs +++ b/src/iOS.Autofill/CredentialProviderViewController.cs @@ -1,4 +1,5 @@ using AuthenticationServices; +using Bit.App.Abstractions; using Bit.App.Resources; using Bit.Core.Abstractions; using Bit.Core.Utilities; @@ -265,7 +266,8 @@ namespace Bit.iOS.Autofill ServiceContainer.Reset(); } iOSCoreHelpers.RegisterLocalServices(); - ServiceContainer.Init(); + var deviceActionService = ServiceContainer.Resolve("deviceActionService"); + ServiceContainer.Init(deviceActionService.DeviceUserAgent); if(!_initedHockeyApp) { iOSCoreHelpers.RegisterHockeyApp(); diff --git a/src/iOS.Core/Services/DeviceActionService.cs b/src/iOS.Core/Services/DeviceActionService.cs index c972c650a..0c7b12604 100644 --- a/src/iOS.Core/Services/DeviceActionService.cs +++ b/src/iOS.Core/Services/DeviceActionService.cs @@ -26,6 +26,7 @@ namespace Bit.iOS.Core.Services private readonly IMessagingService _messagingService; private Toast _toast; private UIAlertController _progressAlert; + private string _userAgent; public DeviceActionService( IStorageService storageService, @@ -35,6 +36,19 @@ namespace Bit.iOS.Core.Services _messagingService = messagingService; } + public string DeviceUserAgent + { + get + { + if(string.IsNullOrWhiteSpace(_userAgent)) + { + _userAgent = $"Bitwarden_Mobile/{Xamarin.Essentials.AppInfo.VersionString} " + + $"(iOS {UIDevice.CurrentDevice.SystemVersion}; Model {UIDevice.CurrentDevice.Model})"; + } + return _userAgent; + } + } + public DeviceType DeviceType => DeviceType.iOS; public bool LaunchApp(string appName) @@ -261,7 +275,7 @@ namespace Bit.iOS.Core.Services public int SystemMajorVersion() { var versionParts = UIDevice.CurrentDevice.SystemVersion.Split('.'); - if(versionParts.Length > 0 && int.TryParse(versionParts[0], out int version)) + if(versionParts.Length > 0 && int.TryParse(versionParts[0], out var version)) { return version; } diff --git a/src/iOS.Extension/LoadingViewController.cs b/src/iOS.Extension/LoadingViewController.cs index bcb9671b5..f68639d4b 100644 --- a/src/iOS.Extension/LoadingViewController.cs +++ b/src/iOS.Extension/LoadingViewController.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using Foundation; using UIKit; @@ -12,6 +12,7 @@ using System.Collections.Generic; using Bit.iOS.Core.Models; using Bit.Core.Utilities; using Bit.Core.Abstractions; +using Bit.App.Abstractions; namespace Bit.iOS.Extension { @@ -386,7 +387,8 @@ namespace Bit.iOS.Extension ServiceContainer.Reset(); } iOSCoreHelpers.RegisterLocalServices(); - ServiceContainer.Init(); + var deviceActionService = ServiceContainer.Resolve("deviceActionService"); + ServiceContainer.Init(deviceActionService.DeviceUserAgent); if(!_initedHockeyApp) { iOSCoreHelpers.RegisterHockeyApp(); @@ -408,4 +410,4 @@ namespace Bit.iOS.Extension return userService.IsAuthenticatedAsync().GetAwaiter().GetResult(); } } -} \ No newline at end of file +} diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs index 26d56aed6..c41e1ceb8 100644 --- a/src/iOS/AppDelegate.cs +++ b/src/iOS/AppDelegate.cs @@ -287,7 +287,8 @@ namespace Bit.iOS iOSCoreHelpers.RegisterLocalServices(); RegisterPush(); - ServiceContainer.Init(); + var deviceActionService = ServiceContainer.Resolve("deviceActionService"); + ServiceContainer.Init(deviceActionService.DeviceUserAgent); iOSCoreHelpers.RegisterHockeyApp(); _pushHandler = new iOSPushNotificationHandler( ServiceContainer.Resolve("pushNotificationListenerService"));