Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

App Center Integration #234

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions HoloLensCommander/HoloLensCommander/Dialogs/SetAPItokenDialog.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<ContentDialog
x:Class="HoloLensCommander.SetAPItokenDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HoloLensCommander"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Set API Token"
PrimaryButtonText="Ok"
SecondaryButtonText="Cancel"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick">

<StackPanel>
<Canvas
Width="350" Height="50">
<TextBlock
x:Name="TokenLabel"
Text="Token"
FontSize="16"
Canvas.Top="16" Canvas.Left="5"/>
<TextBox
x:Name="token"
Text="{Binding Path= APIToken, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ToolTipService.ToolTip="Mobile Center API Token"
Width="200"
Canvas.Top="10" Canvas.Left="85"/>
</Canvas>
</StackPanel>
</ContentDialog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Windows.UI.Xaml.Controls;

// The Content Dialog item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace HoloLensCommander
{
public sealed partial class SetAPItokenDialog : ContentDialog
{
private UserToken apiToken;

public SetAPItokenDialog(UserToken APItoken)
{
this.apiToken = APItoken;
this.DataContext = new SetAPItokenDialogViewModel(APItoken);
this.InitializeComponent();
}

private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
((SetAPItokenDialogViewModel)this.DataContext).UpdateAPItoken(this.apiToken);
}

private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to get rid of this method by not specifying a click event for the secondary button. This is what the Connect to Device dialog does.

{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace HoloLensCommander
{
public partial class SetAPItokenDialogViewModel : INotifyPropertyChanged
{
/// <summary>
/// Event that is notified when a property value has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;

public SetAPItokenDialogViewModel(UserToken apiToken)
{
this.APIToken= apiToken.ApiToken;
}

/// <summary>
/// Sends the PropertyChanged events to registered handlers.
/// </summary>
/// <param name="propertyName">The name of property that has changed.</param>
private void NotifyPropertyChanged(string propertyName)
{
this.PropertyChanged?.Invoke(
this,
new PropertyChangedEventArgs(propertyName));
}

internal void UpdateAPItoken(UserToken apiToken)
{
apiToken.ApiToken = this.APIToken;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HoloLensCommander
{
public partial class SetAPItokenDialogViewModel
{
private string apiToken = string.Empty;
public string APIToken
{
get
{
return this.apiToken;
}
set
{
if (this.apiToken!=value)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this.apiToken != value

{
this.apiToken = value;
this.NotifyPropertyChanged(nameof(APIToken));
}
}
}
}
}
10 changes: 10 additions & 0 deletions HoloLensCommander/HoloLensCommander/HoloLensCommander.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@
<Compile Include="Dialogs\ManageAppsDialogViewModelProperties.cs" />
<Compile Include="Dialogs\MixedRealityViewDialogViewModel.cs" />
<Compile Include="Dialogs\MixedRealityViewDialogViewModelProperties.cs" />
<Compile Include="Dialogs\SetAPItokenDialog.xaml.cs">
<DependentUpon>SetAPItokenDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\SetAPItokenDialogViewModel.cs" />
<Compile Include="Dialogs\SetAPItokenDialogViewModelProperties.cs" />
<Compile Include="Dialogs\SetCredentialsDialogViewModel.cs" />
<Compile Include="Dialogs\SetCredentialsDialogViewModelProperties.cs" />
<Compile Include="Dialogs\SetIpdDialog.xaml.cs">
Expand Down Expand Up @@ -174,6 +179,7 @@
<Compile Include="Utilities\Settings.cs" />
<Compile Include="Utilities\TagInformation.cs" />
<Compile Include="Utilities\UserInformation.cs" />
<Compile Include="Utilities\UserToken.cs" />
<Compile Include="Utilities\Utilities.cs" />
</ItemGroup>
<ItemGroup>
Expand Down Expand Up @@ -212,6 +218,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Dialogs\SetAPItokenDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Dialogs\SetIpdDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand Down
7 changes: 7 additions & 0 deletions HoloLensCommander/HoloLensCommander/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@
Command="{Binding Path=UseDesktopFilterCommand}"
HorizontalAlignment="Left" Width="130"
Canvas.Left="545" Canvas.Top="8"/>
<Button
Content="&#xEE57;"
ToolTipService.ToolTip="Enter API token"
Command="{Binding Path=ShowSetAPItokenCommand}"
FontFamily="Segoe MDL2 Assets"
Width="50" Height="40"
Canvas.Top="5" Canvas.Left="675"/>
</Canvas>
<ScrollViewer Grid.Column="1" Grid.Row="1"
VerticalScrollBarVisibility="Auto" VerticalScrollMode="Auto">
Expand Down
7 changes: 7 additions & 0 deletions HoloLensCommander/HoloLensCommander/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ partial class MainWindowViewModel : INotifyPropertyChanged, IDisposable
/// Values used to store and retrieve settings data.
/// </summary>
private static readonly string AutoReconnectKey = "autoReconnect";
private static readonly string DefaultAPItokenKey = "defaultAPItokenKey";
private static readonly string DefaultNetworkKeyKey = "defaultNetworkKey";
private static readonly string DefaultPasswordKey = "defaultPassword";
private static readonly string DefaultSsidKey = "defaultSsid";
Expand Down Expand Up @@ -375,6 +376,12 @@ await this.ConnectToDeviceAsync(
this.SelectAllDevices();
});

this.ShowSetAPItokenCommand = new Command(
async (parameter) =>
{
await this.ShowSetAPItoken();
});

this.ShowSetCredentialsCommand = new Command(
async (parameter) =>
{
Expand Down
21 changes: 21 additions & 0 deletions HoloLensCommander/HoloLensCommander/MainWindowViewModelCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,23 @@ private async Task ShowSetCredentials()
}
}

public ICommand ShowSetAPItokenCommand
{ get; private set; }

private async Task ShowSetAPItoken()
{
UserToken apiToken = new UserToken(this.ApiToken);

SetAPItokenDialog apiTokenDialogs = new SetAPItokenDialog(apiToken);
ContentDialogResult dialogResult = await apiTokenDialogs.ShowAsync();

if (dialogResult==ContentDialogResult.Primary)
{
this.ApiToken = apiToken.ApiToken;
this.SaveApplicationSettings();
}
}

/// <summary>
/// Command used to display the settings dialog.
/// </summary>
Expand Down Expand Up @@ -860,6 +877,8 @@ private void LoadApplicationSettings()
this.UserName = this.appSettings.Values[DefaultUserNameKey] as string;
this.Password = this.appSettings.Values[DefaultPasswordKey] as string;

this.ApiToken = this.appSettings.Values[DefaultAPItokenKey] as string;

this.defaultSsid = this.appSettings.Values[DefaultSsidKey] as string;
this.defaultNetworkKey = this.appSettings.Values[DefaultNetworkKeyKey] as string;

Expand Down Expand Up @@ -983,6 +1002,8 @@ private void SaveApplicationSettings()
this.appSettings.Values[DefaultUserNameKey] = this.UserName;
this.appSettings.Values[DefaultPasswordKey] = this.Password;

this.appSettings.Values[DefaultAPItokenKey] = this.ApiToken;

this.appSettings.Values[DefaultSsidKey] = this.defaultSsid;
this.appSettings.Values[DefaultNetworkKeyKey] = this.defaultNetworkKey;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,44 @@ private set
}
}

/// <summary>
/// Gets or sets the API Token to be used when connecting to mobile center.
/// </summary>
private string apiToken = string.Empty;
public string ApiToken
{
get
{
return this.apiToken;
}

set
{
if (this.apiToken != value)
{
this.apiToken = value;
this.UpdateAPItoken();
}
}
}

private bool apiTokenSet = false;
public bool ApiTokenSet
{
get
{
return this.apiTokenSet;
}
set
{
if (apiTokenSet!=value)
{
apiTokenSet = value;
this.NotifyPropertyChanged("APItokenSet");
}
}
}

/// <summary>
/// Gets a value indicating whether or not the application management controls are to be enabled.
/// </summary>
Expand Down Expand Up @@ -238,6 +276,18 @@ private set
}
}

private void UpdateAPItoken()
{
bool haveAPItoken = false;

if (!string.IsNullOrWhiteSpace(this.ApiToken))
{
haveAPItoken = true;
}

this.ApiTokenSet = haveAPItoken;
}

/// <summary>
/// Updates whether or not connections are safe to be restored.
/// </summary>
Expand Down
18 changes: 18 additions & 0 deletions HoloLensCommander/HoloLensCommander/Utilities/UserToken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HoloLensCommander
{
public class UserToken

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we will need anything other than the token string?
Is the token string in a special format that should be validated?
If not, I would recommend removing the UserToken class and just use the string throughout.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidkline-ms No, so far I have only needed the token. I am also working to add username and password support, but am using a NetworkCredentials object for that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe encapsulate everything here (network credential / token string)? i definitely recommend requiring the user to enter credentials at least on first use during a session. these credentials would pose a security risk.

As an asside, i am considering removing the device portal credential storage in a future release

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I agree it should definitely not be stored as plain text. What about storing it as a secure string? What kind of credential manager is built in to UWP apps?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SecureString may work, but I haven't tried storing it in a config file. Havent researched credential manangement in UWP apps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.microsoft.com/en-us/appcenter/api-docs/ This is what we're attempting to use. App Center recommends issuing a token to make API calls. I can't find any docs on app center for how to use OAuth. Do you know how?

{
public UserToken(string apiToken)
{
ApiToken = apiToken;
}

public string ApiToken { get; set; }
}
}