Skip to content

Commit 97fcbb7

Browse files
committed
Added setting for API keys and automated the oauth steps if insufficient authentication data
1 parent f637811 commit 97fcbb7

34 files changed

+264
-61
lines changed

WBS.Net/UserSecrets.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace WBS.Net
8+
{
9+
public class UserSecrets
10+
{
11+
public string Token
12+
{
13+
get;
14+
set;
15+
}
16+
17+
public string TokenSecret
18+
{
19+
get;
20+
set;
21+
}
22+
23+
public int UserId
24+
{
25+
get;
26+
set;
27+
}
28+
}
29+
}

WBS.Net/WBS.Net.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<ItemGroup>
4747
<Compile Include="Measure.cs" />
4848
<Compile Include="User.cs" />
49+
<Compile Include="UserSecrets.cs" />
4950
<Compile Include="WBS.cs" />
5051
<Compile Include="Properties\AssemblyInfo.cs" />
5152
</ItemGroup>

WBS.Net/WBS.cs

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using DevDefined.OAuth.Framework;
1414
using DevDefined.OAuth.Storage.Basic;
1515
using DevDefined.OAuth.Tests;
16+
using System.Xml.Serialization;
1617

1718
namespace WBS.Net
1819
{
@@ -22,7 +23,8 @@ public class WBS
2223
private readonly string consumerSecret;
2324
private string token;
2425
private string tokenSecret;
25-
private int userId;
26+
private int userId = -1;
27+
private string userSecretsPath;
2628

2729
private const string requestUrl = "http://oauth.withings.com/account/request_token";
2830
private const string userAuthorizeUrl = "http://oauth.withings.com/account/authorize";
@@ -31,20 +33,40 @@ public class WBS
3133
private IToken requestToken;
3234
private OAuthConsumerContext context;
3335

34-
public User User { get; private set; }
36+
public User User
37+
{
38+
get;
39+
private set;
40+
}
41+
42+
public bool IsValid
43+
{
44+
get
45+
{
46+
return (!string.IsNullOrEmpty(this.token) && !string.IsNullOrEmpty(this.tokenSecret) && userId != -1);
47+
}
48+
}
3549

36-
public WBS(string consumerKey, string consumerSecret, string token = "", string tokenSecret = "", int userId = -1)
50+
public WBS(string consumerKey, string consumerSecret)
3751
{
52+
this.userSecretsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "UserSecrets.xml");
3853
this.consumerKey = consumerKey;
3954
this.consumerSecret = consumerSecret;
55+
this.CreateSession();
56+
this.LoadSecrets(this.userSecretsPath);
57+
}
58+
59+
public WBS(string consumerKey, string consumerSecret, string token, string tokenSecret, int userId)
60+
: this(consumerKey, consumerSecret)
61+
{
4062
this.tokenSecret = tokenSecret;
4163
this.token = token;
4264
this.userId = userId;
4365

44-
this.CreateSession();
45-
46-
if (!string.IsNullOrWhiteSpace(this.token) && !string.IsNullOrWhiteSpace(this.tokenSecret) && userId != -1)
66+
if (this.IsValid)
67+
{
4768
this.UpdateProfil();
69+
}
4870
}
4971

5072
public async Task<string> Connect()
@@ -81,6 +103,7 @@ await Task.Run(() =>
81103
this.userId = userId;
82104

83105
this.UpdateProfil();
106+
this.SaveSecrets(this.userSecretsPath);
84107
});
85108
}
86109

@@ -127,7 +150,7 @@ private async Task<List<MeasureGroup>> Get(string request)
127150
string responseText = session.Request(accessToken).Get().ForUrl(request).ToString();
128151
return TransformMeasures(responseText);
129152
}
130-
catch (WebException ex)
153+
catch (WebException)
131154
{
132155
throw;
133156
}
@@ -213,17 +236,55 @@ await Task.Run(() =>
213236
});
214237
}
215238

216-
public static DateTime FromUnixTime(long unixTime)
239+
private static DateTime FromUnixTime(long unixTime)
217240
{
218241
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
219242
return epoch.AddSeconds(unixTime);
220243
}
221244

222-
public static long ToUnixTime(DateTime date)
245+
private static long ToUnixTime(DateTime date)
223246
{
224247
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
225248
return Convert.ToInt64((date - epoch).TotalSeconds);
226249
}
227250

251+
private void SaveSecrets(string userSecretsPath)
252+
{
253+
try
254+
{
255+
UserSecrets secrets = new UserSecrets
256+
{
257+
Token = this.token,
258+
TokenSecret = this.tokenSecret,
259+
UserId = this.userId
260+
};
261+
262+
var serializer = new XmlSerializer(typeof(UserSecrets));
263+
TextWriter writer = new StreamWriter(userSecretsPath);
264+
serializer.Serialize(writer, secrets);
265+
writer.Close();
266+
}
267+
catch(Exception)
268+
{ }
269+
}
270+
271+
private void LoadSecrets(string userSecretsPath)
272+
{
273+
try
274+
{
275+
var serializer = new XmlSerializer(typeof(UserSecrets));
276+
FileStream fs = new FileStream(userSecretsPath, FileMode.Open);
277+
278+
var secrets = serializer.Deserialize(fs) as UserSecrets;
279+
fs.Close();
280+
281+
this.token = secrets.Token;
282+
this.tokenSecret = secrets.TokenSecret;
283+
this.userId = secrets.UserId;
284+
}
285+
catch(Exception)
286+
{ }
287+
}
288+
228289
}
229290
}

WBS.Net/bin/Debug/WBS.Net.dll

1.5 KB
Binary file not shown.

WBS.Net/bin/Debug/WBS.Net.pdb

2 KB
Binary file not shown.
Binary file not shown.

WBS.Net/obj/Debug/WBS.Net.csproj.FileListAbsolute.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@ C:\Users\Stumpy\Documents\GitHub\WBS.Net\WBS.Net\bin\Debug\DevDefined.OAuth.dll
44
C:\Users\Stumpy\Documents\GitHub\WBS.Net\WBS.Net\obj\Debug\WBS.Net.csprojResolveAssemblyReference.cache
55
C:\Users\Stumpy\Documents\GitHub\WBS.Net\WBS.Net\obj\Debug\WBS.Net.dll
66
C:\Users\Stumpy\Documents\GitHub\WBS.Net\WBS.Net\obj\Debug\WBS.Net.pdb
7+
C:\RND\WBS.Net\WBS.Net\bin\Debug\WBS.Net.dll
8+
C:\RND\WBS.Net\WBS.Net\bin\Debug\WBS.Net.pdb
9+
C:\RND\WBS.Net\WBS.Net\bin\Debug\DevDefined.OAuth.dll
10+
C:\RND\WBS.Net\WBS.Net\obj\Debug\WBS.Net.csprojResolveAssemblyReference.cache
11+
C:\RND\WBS.Net\WBS.Net\obj\Debug\WBS.Net.dll
12+
C:\RND\WBS.Net\WBS.Net\obj\Debug\WBS.Net.pdb
Binary file not shown.

WBS.Net/obj/Debug/WBS.Net.dll

1.5 KB
Binary file not shown.

WBS.Net/obj/Debug/WBS.Net.pdb

2 KB
Binary file not shown.

Wbs.Sample/App.config

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<configuration>
3+
<configSections>
4+
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
5+
<section name="Wbs.Sample.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
6+
</sectionGroup>
7+
</configSections>
38
<startup>
49
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
510
</startup>
@@ -11,4 +16,14 @@
1116
</dependentAssembly>
1217
</assemblyBinding>
1318
</runtime>
19+
<applicationSettings>
20+
<Wbs.Sample.Properties.Settings>
21+
<setting name="ApiKey" serializeAs="String">
22+
<value>Your API Key</value>
23+
</setting>
24+
<setting name="ApiSecret" serializeAs="String">
25+
<value>Your API Scret</value>
26+
</setting>
27+
</Wbs.Sample.Properties.Settings>
28+
</applicationSettings>
1429
</configuration>

Wbs.Sample/MainWindow.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
Title="MainWindow" Height="800" Width="1024">
55
<Grid>
6-
<WebBrowser x:Name="WebBrowser" />
6+
<WebBrowser x:Name="WebBrowser" />
77
</Grid>
88
</Window>

Wbs.Sample/MainWindow.xaml.cs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,14 @@ namespace Wbs.Sample
2020
/// </summary>
2121
public partial class MainWindow : Window
2222
{
23-
private const string consumerKey = "8232ce439c8236c240156d7955423239cc44621ed3668c03fd17b1f30";
24-
private const string consumerSecret = "2f7401d0c5707fb3cd951bc07c7c4d9c1657d8ce284fc47e669d633b0552479";
25-
private const string token = "c99115c176cdb3154f919c24d3cc7bd694c36301521e9c7ddd8e421c329454";
26-
private const string tokenSecret = "e6c9e10997c7888c5e6c485b6e6079b88ffeedf8d95cbff7194c0055c46";
27-
private const int userId = 815991;
28-
29-
WBS.Net.WBS wbs = new WBS.Net.WBS(
30-
consumerKey,
31-
consumerSecret,
32-
token, // optionnal
33-
tokenSecret, // optionnal
34-
userId); // optionnal
35-
// if you dont see these optionnal parameter, you will need to manage the oauth validation (see below)
23+
//private const string consumerKey = "8232ce439c8236c240156d7955423239cc44621ed3668c03fd17b1f30";
24+
//private const string consumerSecret = "2f7401d0c5707fb3cd951bc07c7c4d9c1657d8ce284fc47e669d633b0552479";
25+
//private const string token = "c99115c176cdb3154f919c24d3cc7bd694c36301521e9c7ddd8e421c329454";
26+
//private const string tokenSecret = "e6c9e10997c7888c5e6c485b6e6079b88ffeedf8d95cbff7194c0055c46";
27+
//private const int userId = 2168435;
3628

29+
WBS.Net.WBS wbs = new WBS.Net.WBS(Properties.Settings.Default.ApiKey, Properties.Settings.Default.ApiSecret);
30+
3731
public MainWindow()
3832
{
3933
InitializeComponent();
@@ -44,14 +38,31 @@ public MainWindow()
4438
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
4539
{
4640
// already logued so we can directly get Measures
47-
var list = await wbs.GetMeasures(DateTime.Now.AddYears(-1), DateTime.Now);
41+
if (wbs.IsValid)
42+
{
43+
var list = await wbs.GetMeasures(DateTime.Now.AddYears(-1), DateTime.Now);
4844

49-
// if we dont have token, tokenSecret and userId, we need to get a oauth token
50-
//var url = await wbs.Connect();
51-
//this.WebBrowser.LoadCompleted += WebBrowser_LoadCompleted;
52-
//this.WebBrowser.Source = new Uri(url);
45+
var heartData = from x in list
46+
from m in x.Measures
47+
where m.MeasureType == WBS.Net.MeasureType.HeartPulse
48+
select new { Date = x.Date, Pulse = m.Value };
49+
}
50+
else
51+
{
52+
// if we dont have token, tokenSecret and userId, we need to get a oauth token
53+
var url = await wbs.Connect();
54+
this.WebBrowser.LoadCompleted += WebBrowser_LoadCompleted;
55+
this.WebBrowser.Source = new Uri(url);
56+
}
5357
}
5458

59+
//
60+
// Note - you may find that the allow buttons don't show up in the Withings page.
61+
// This is because of IE compatibility defaulting in the WebBrowser control. You need to add a registry key
62+
// for your application to force a later version of IE. I found IE 9 compatitibility works (value 9999)
63+
// On windows 8.1 I needed to add it to HKEY_CURRENT_USER. When I added it to HKEY_LOCAL_MACHINE is did not work.
64+
// More detail about this can be found here: http://msdn.microsoft.com/en-us/library/ee330730%28VS.85%29.aspx#browser_emulation
65+
5566
void WebBrowser_LoadCompleted(object sender, NavigationEventArgs e)
5667
{
5768
if (e.Uri.OriginalString.Contains("oauth_verifier"))

Wbs.Sample/Properties/Settings.Designer.cs

Lines changed: 28 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<?xml version='1.0' encoding='utf-8'?>
2-
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
3-
<Profiles>
4-
<Profile Name="(Default)" />
5-
</Profiles>
6-
<Settings />
2+
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Wbs.Sample.Properties" GeneratedClassName="Settings">
3+
<Profiles />
4+
<Settings>
5+
<Setting Name="ApiKey" Type="System.String" Scope="Application">
6+
<Value Profile="(Default)">Your API Key</Value>
7+
</Setting>
8+
<Setting Name="ApiSecret" Type="System.String" Scope="Application">
9+
<Value Profile="(Default)">Your API Scret</Value>
10+
</Setting>
11+
</Settings>
712
</SettingsFile>

Wbs.Sample/Settings.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace Wbs.Sample.Properties {
2+
3+
4+
// This class allows you to handle specific events on the settings class:
5+
// The SettingChanging event is raised before a setting's value is changed.
6+
// The PropertyChanged event is raised after a setting's value is changed.
7+
// The SettingsLoaded event is raised after the setting values are loaded.
8+
// The SettingsSaving event is raised before the setting values are saved.
9+
internal sealed partial class Settings {
10+
11+
public Settings() {
12+
// // To add event handlers for saving and changing settings, uncomment the lines below:
13+
//
14+
// this.SettingChanging += this.SettingChangingEventHandler;
15+
//
16+
// this.SettingsSaving += this.SettingsSavingEventHandler;
17+
//
18+
}
19+
20+
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
21+
// Add code to handle the SettingChangingEvent event here.
22+
}
23+
24+
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
25+
// Add code to handle the SettingsSaving event here.
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)