device registration on login

This commit is contained in:
Kyle Spearrin 2016-06-21 22:29:29 -04:00
parent 0f5b2f5721
commit 4cfa8e2dee
18 changed files with 154 additions and 15 deletions

View file

@ -123,6 +123,14 @@
<HintPath>..\..\packages\Plugin.CurrentActivity.1.0.1\lib\MonoAndroid10\Plugin.CurrentActivity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.DeviceInfo, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.DeviceInfo.2.0.2\lib\MonoAndroid10\Plugin.DeviceInfo.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.DeviceInfo.Abstractions, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.DeviceInfo.2.0.2\lib\MonoAndroid10\Plugin.DeviceInfo.Abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.Fingerprint, Version=1.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Plugin.Fingerprint.1.1.1-beta\lib\MonoAndroid\Plugin.Fingerprint.dll</HintPath>
<Private>True</Private>

View file

@ -11,6 +11,7 @@ using Bit.App.Services;
using Microsoft.Practices.Unity;
using Plugin.Connectivity;
using Plugin.CurrentActivity;
using Plugin.DeviceInfo;
using Plugin.Fingerprint;
using Plugin.Settings;
using PushNotification.Plugin;
@ -119,6 +120,7 @@ namespace Bit.Android
.RegisterType<ISyncService, SyncService>(new ContainerControlledLifetimeManager())
.RegisterType<IClipboardService, ClipboardService>(new ContainerControlledLifetimeManager())
.RegisterType<IPushNotificationListener, PushNotificationListener>(new ContainerControlledLifetimeManager())
.RegisterType<IAppIdService, AppIdService>(new ContainerControlledLifetimeManager())
// Repositories
.RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager())
@ -127,12 +129,13 @@ namespace Bit.Android
.RegisterType<IAuthApiRepository, AuthApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IDeviceApiRepository, DeviceApiRepository>(new ContainerControlledLifetimeManager())
// Other
.RegisterInstance(CrossDeviceInfo.Current, new ContainerControlledLifetimeManager())
.RegisterInstance(CrossSettings.Current, new ContainerControlledLifetimeManager())
.RegisterInstance(CrossConnectivity.Current, new ContainerControlledLifetimeManager())
.RegisterInstance(UserDialogs.Instance, new ContainerControlledLifetimeManager())
.RegisterInstance(CrossFingerprint.Current, new ContainerControlledLifetimeManager());
CrossPushNotification.Initialize(container.Resolve<IPushNotificationListener>(), "SENDERID");
CrossPushNotification.Initialize(container.Resolve<IPushNotificationListener>(), "SECRET_SENDER_ID");
container.RegisterInstance(CrossPushNotification.Current, new ContainerControlledLifetimeManager());
Resolver.SetResolver(new UnityResolver(container));

View file

@ -11,6 +11,7 @@
<package id="SQLitePCL.raw" version="0.8.6" targetFramework="monoandroid60" />
<package id="Unity" version="3.5.1405-prerelease" targetFramework="monoandroid60" />
<package id="Xam.Plugin.Connectivity" version="2.1.2" targetFramework="monoandroid60" />
<package id="Xam.Plugin.DeviceInfo" version="2.0.2" targetFramework="monoandroid60" />
<package id="Xam.Plugin.PushNotification" version="1.2.2" targetFramework="monoandroid60" developmentDependency="true" />
<package id="Xam.Plugins.Settings" version="2.1.0" targetFramework="monoandroid60" />
<package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="23.3.0" targetFramework="monoandroid60" />

View file

@ -2,9 +2,12 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models.Api;
using Bit.App.Repositories;
namespace Bit.App.Abstractions
{
public interface IDeviceApiRepository : IApiRepository<DeviceRequest, DeviceResponse, string>
{ }
{
Task<ApiResult<DeviceResponse>> PutTokenAsync(string identifier, DeviceTokenRequest request);
}
}

View file

@ -0,0 +1,7 @@
namespace Bit.App.Abstractions
{
public interface IAppIdService
{
string AppId { get; }
}
}

View file

@ -36,6 +36,8 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Abstractions\Repositories\IDeviceApiRepository.cs" />
<Compile Include="Abstractions\Services\IAppIdService.cs" />
<Compile Include="Abstractions\Services\IAuthService.cs" />
<Compile Include="Abstractions\Services\IClipboardService.cs" />
<Compile Include="Abstractions\Services\ISiteService.cs" />
<Compile Include="Abstractions\Services\IFolderService.cs" />
@ -65,6 +67,7 @@
<Compile Include="Enums\ReturnType.cs" />
<Compile Include="Models\Api\ApiError.cs" />
<Compile Include="Models\Api\ApiResult.cs" />
<Compile Include="Models\Api\Request\DeviceTokenRequest.cs" />
<Compile Include="Models\Api\Request\FolderRequest.cs" />
<Compile Include="Models\Api\Request\DeviceRequest.cs" />
<Compile Include="Models\Api\Request\SiteRequest.cs" />
@ -117,10 +120,10 @@
<DesignTime>True</DesignTime>
<DependentUpon>AppResources.resx</DependentUpon>
</Compile>
<Compile Include="Services\AppIdService.cs" />
<Compile Include="Services\DatabaseService.cs" />
<Compile Include="Services\FolderService.cs" />
<Compile Include="Repositories\Repository.cs" />
<Compile Include="Abstractions\Services\IAuthService.cs" />
<Compile Include="Abstractions\Services\ICryptoService.cs" />
<Compile Include="Abstractions\Services\IDatabaseService.cs" />
<Compile Include="Abstractions\Services\ISyncService.cs" />
@ -140,7 +143,9 @@
<Compile Include="Utilities\TokenHttpRequestMessage.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Reference Include="Acr.UserDialogs, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
@ -179,6 +184,14 @@
<HintPath>..\..\packages\Xam.Plugin.Connectivity.2.1.2\lib\portable-net45+wp80+wp81+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+Xamarin.Mac20+UAP10\Plugin.Connectivity.Abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.DeviceInfo, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.DeviceInfo.2.0.2\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.DeviceInfo.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.DeviceInfo.Abstractions, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.DeviceInfo.2.0.2\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.DeviceInfo.Abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.Fingerprint, Version=1.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Plugin.Fingerprint.1.1.1-beta\lib\portable-net45+win8+wpa81+wp8\Plugin.Fingerprint.dll</HintPath>
<Private>True</Private>

View file

@ -1,11 +1,23 @@
using PushNotification.Plugin.Abstractions;
using Bit.App.Abstractions;
using Plugin.DeviceInfo.Abstractions;
using PushNotification.Plugin.Abstractions;
namespace Bit.App.Models.Api
{
public class DeviceRequest
{
public DeviceRequest() { }
public DeviceRequest(IAppIdService appIdService, IDeviceInfo deviceInfo)
{
Identifier = appIdService.AppId;
Name = deviceInfo.Model;
Type = deviceInfo.Platform == Platform.Android ? DeviceType.Android : DeviceType.iOS;
}
public DeviceType Type { get; set; }
public string Name { get; set; }
public string Identifier { get; set; }
public string PushToken { get; set; }
}
}

View file

@ -0,0 +1,12 @@
namespace Bit.App.Models.Api
{
public class DeviceTokenRequest
{
public DeviceTokenRequest(string token)
{
PushToken = token;
}
public string PushToken { get; set; }
}
}

View file

@ -4,5 +4,6 @@
{
public string Email { get; set; }
public string MasterPasswordHash { get; set; }
public DeviceRequest Device { get; set; }
}
}

View file

@ -7,6 +7,7 @@ namespace Bit.App.Models.Api
{
public string Id { get; set; }
public string Name { get; set; }
public string Identifier { get; set; }
public DeviceType Type { get; set; }
public DateTime CreationDate { get; set; }
}

View file

@ -7,6 +7,7 @@ using Bit.App.Abstractions;
using Bit.App.Behaviors;
using Bit.App.Models.Api;
using Bit.App.Resources;
using Plugin.DeviceInfo.Abstractions;
using Xamarin.Forms;
using XLabs.Ioc;
@ -18,6 +19,8 @@ namespace Bit.App.Pages
{
var cryptoService = Resolver.Resolve<ICryptoService>();
var authService = Resolver.Resolve<IAuthService>();
var deviceInfo = Resolver.Resolve<IDeviceInfo>();
var appIdService = Resolver.Resolve<IAppIdService>();
var emailEntry = new Entry
{
@ -58,13 +61,14 @@ namespace Bit.App.Pages
var request = new TokenRequest
{
Email = emailEntry.Text,
MasterPasswordHash = cryptoService.HashPasswordBase64(key, masterPasswordEntry.Text)
MasterPasswordHash = cryptoService.HashPasswordBase64(key, masterPasswordEntry.Text),
Device = new DeviceRequest(appIdService, deviceInfo)
};
var response = await authService.TokenPostAsync(request);
if(!response.Succeeded)
{
await DisplayAlert(AppResources.AnErrorHasOccurred, response.Errors.First().Message, AppResources.Ok);
await DisplayAlert(AppResources.AnErrorHasOccurred, response.Errors.FirstOrDefault()?.Message, AppResources.Ok);
return;
}

View file

@ -1,11 +1,33 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Models.Api;
using Newtonsoft.Json;
namespace Bit.App.Repositories
{
public class DeviceApiRepository : ApiRepository<DeviceRequest, DeviceResponse, string>, IDeviceApiRepository
{
protected override string ApiRoute => "devices";
public virtual async Task<ApiResult<DeviceResponse>> PutTokenAsync(string identifier, DeviceTokenRequest request)
{
var requestMessage = new TokenHttpRequestMessage(request)
{
Method = HttpMethod.Put,
RequestUri = new Uri(Client.BaseAddress, string.Concat(ApiRoute, "/identifier/", identifier, "/token")),
};
var response = await Client.SendAsync(requestMessage);
if(!response.IsSuccessStatusCode)
{
return await HandleErrorAsync<DeviceResponse>(response);
}
var responseContent = await response.Content.ReadAsStringAsync();
var responseObj = JsonConvert.DeserializeObject<DeviceResponse>(responseContent);
return ApiResult<DeviceResponse>.Success(responseObj, response.StatusCode);
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using Bit.App.Abstractions;
using Plugin.Settings.Abstractions;
namespace Bit.App.Services
{
public class AppIdService : IAppIdService
{
private const string AppIdKey = "appId";
private readonly ISettings _settings;
private string _appId;
public AppIdService(ISettings settings)
{
_settings = settings;
}
public string AppId
{
get
{
if(!string.IsNullOrWhiteSpace(_appId))
{
return _appId;
}
_appId = _settings.GetValueOrDefault<string>(AppIdKey);
if(!string.IsNullOrWhiteSpace(_appId))
{
return _appId;
}
_appId = Guid.NewGuid().ToString();
_settings.AddOrUpdateValue(AppIdKey, _appId);
return _appId;
}
}
}
}

View file

@ -9,6 +9,8 @@ using PushNotification.Plugin;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Bit.App.Abstractions;
using Xamarin.Forms;
using Plugin.DeviceInfo.Abstractions;
namespace Bit.App.Services
{
@ -18,15 +20,18 @@ namespace Bit.App.Services
private readonly ISyncService _syncService;
private readonly IDeviceApiRepository _deviceApiRepository;
private readonly IAuthService _authService;
private readonly IAppIdService _appIdService;
public PushNotificationListener(
ISyncService syncService,
IDeviceApiRepository deviceApiRepository,
IAuthService authService)
IAuthService authService,
IAppIdService appIdService)
{
_syncService = syncService;
_deviceApiRepository = deviceApiRepository;
_authService = authService;
_appIdService = appIdService;
}
public void OnMessage(JObject values, DeviceType deviceType)
@ -44,13 +49,8 @@ namespace Bit.App.Services
return;
}
var response = _deviceApiRepository.PostAsync(new Models.Api.DeviceRequest
{
Name = deviceType.ToString(),
Type = deviceType,
PushToken = token
}).GetAwaiter().GetResult();
var response = _deviceApiRepository.PutTokenAsync(_appIdService.AppId, new Models.Api.DeviceTokenRequest(token))
.GetAwaiter().GetResult();
if(response.Succeeded)
{
Debug.WriteLine("Registered device with server.");

View file

@ -11,6 +11,7 @@
<package id="SQLitePCL.raw" version="0.8.6" targetFramework="portable45-net45+win8+wpa81" />
<package id="Unity" version="3.5.1405-prerelease" targetFramework="portable45-net45+win8+wpa81" />
<package id="Xam.Plugin.Connectivity" version="2.1.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="Xam.Plugin.DeviceInfo" version="2.0.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="Xam.Plugin.PushNotification" version="1.2.2" targetFramework="portable45-net45+win8+wpa81" developmentDependency="true" />
<package id="Xam.Plugins.Settings" version="2.1.0" targetFramework="portable45-net45+win8+wpa81" />
<package id="Xamarin.Forms" version="2.2.0.31" targetFramework="portable45-net45+win8+wpa81" />

View file

@ -22,6 +22,7 @@ using Xamarin.Forms;
using Bit.App;
using Bit.iOS.Core.Services;
using PushNotification.Plugin;
using Plugin.DeviceInfo;
namespace Bit.iOS
{
@ -187,6 +188,7 @@ namespace Bit.iOS
.RegisterType<ISyncService, SyncService>(new ContainerControlledLifetimeManager())
.RegisterType<IClipboardService, ClipboardService>(new ContainerControlledLifetimeManager())
.RegisterType<IPushNotificationListener, PushNotificationListener>(new ContainerControlledLifetimeManager())
.RegisterType<IAppIdService, AppIdService>(new ContainerControlledLifetimeManager())
// Repositories
.RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager())
@ -195,6 +197,7 @@ namespace Bit.iOS
.RegisterType<IAuthApiRepository, AuthApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IDeviceApiRepository, DeviceApiRepository>(new ContainerControlledLifetimeManager())
// Other
.RegisterInstance(CrossDeviceInfo.Current, new ContainerControlledLifetimeManager())
.RegisterInstance(CrossSettings.Current, new ContainerControlledLifetimeManager())
.RegisterInstance(CrossConnectivity.Current, new ContainerControlledLifetimeManager())
.RegisterInstance(UserDialogs.Instance, new ContainerControlledLifetimeManager())

View file

@ -180,6 +180,14 @@
<HintPath>..\..\packages\Xam.Plugin.Connectivity.2.1.2\lib\Xamarin.iOS10\Plugin.Connectivity.Abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.DeviceInfo, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.DeviceInfo.2.0.2\lib\Xamarin.iOS10\Plugin.DeviceInfo.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.DeviceInfo.Abstractions, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.DeviceInfo.2.0.2\lib\Xamarin.iOS10\Plugin.DeviceInfo.Abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.Fingerprint, Version=1.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Plugin.Fingerprint.1.1.1-beta\lib\Xamarin.iOS10\Plugin.Fingerprint.dll</HintPath>
<Private>True</Private>

View file

@ -11,6 +11,7 @@
<package id="SQLitePCL.raw" version="0.8.6" targetFramework="xamarinios10" />
<package id="Unity" version="3.5.1405-prerelease" targetFramework="xamarinios10" />
<package id="Xam.Plugin.Connectivity" version="2.1.2" targetFramework="xamarinios10" />
<package id="Xam.Plugin.DeviceInfo" version="2.0.2" targetFramework="xamarinios10" />
<package id="Xam.Plugin.PushNotification" version="1.2.2" targetFramework="xamarinios10" developmentDependency="true" />
<package id="Xam.Plugins.Settings" version="2.1.0" targetFramework="xamarinios10" />
<package id="Xamarin.Forms" version="2.2.0.31" targetFramework="xamarinios10" />