-
Notifications
You must be signed in to change notification settings - Fork 17
/
UserManager.cs
159 lines (136 loc) · 5.5 KB
/
UserManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util.Store;
using Grpc.Auth;
using Grpc.Core;
using Newtonsoft.Json;
using Timer = System.Timers.Timer;
namespace GoogleAssistantWindows
{
/// <summary>
/// Handles the OAuth2 Credentials
/// </summary>
public class UserManager
{
private const int TokenRefreshTime = 1000 * 60 * 50; // token expires every 60 mins for assistant? The token says 3600s, maybe need to renew the token every minute?
private UserCredential _credential;
private Timer _tokenRefreshTimer;
private GoogleUserData _userData;
public delegate void UserUpdateDelegate(GoogleUserData userData);
public event UserUpdateDelegate OnUserUpdate;
private static UserManager _instance;
public static UserManager Instance
{
get
{
if (_instance == null)
_instance = new UserManager();
return _instance;
}
}
public ChannelCredentials GetChannelCredential()
{
return _credential.ToChannelCredentials();
}
public bool IsSignedIn => _credential != null;
public void SignOut()
{
if (_credential != null)
{
if (_tokenRefreshTimer != null)
_tokenRefreshTimer.Stop();
_credential.RevokeTokenAsync(CancellationToken.None).Wait();
foreach (string file in Directory.EnumerateFiles(Utils.GetDataStoreFolder()))
{
if (file.Contains("-user"))
{
File.Delete(file);
return;
}
}
}
_credential = null;
}
public async Task GetOrRefreshCredential()
{
if (_credential == null)
{
using (var stream = new FileStream(@"Secrets\client_id.json", FileMode.Open, FileAccess.Read))
{
_credential =
await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
Const.Scope, Const.User, CancellationToken.None, new FileDataStore(Const.Folder));
await _credential.RefreshTokenAsync(CancellationToken.None);
await GetGooglePlusUserData(_credential.Token.AccessToken);
OnUserUpdate?.Invoke(_userData);
StartRefreshTimer();
}
}
else
{
await _credential.RefreshTokenAsync(CancellationToken.None);
}
}
private void CreateRefreshTimer()
{
_tokenRefreshTimer = new Timer { Interval = TokenRefreshTime };
_tokenRefreshTimer.Elapsed += (sender2, args) => { GetOrRefreshCredential(); };
}
private void StartRefreshTimer()
{
if (_tokenRefreshTimer == null)
CreateRefreshTimer();
_tokenRefreshTimer.Start();
}
private async Task GetGooglePlusUserData(string accessToken)
{
try
{
HttpClient client = new HttpClient();
var urlProfile = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken;
client.CancelPendingRequests();
HttpResponseMessage output = await client.GetAsync(urlProfile);
if (output.IsSuccessStatusCode)
{
string outputData = await output.Content.ReadAsStringAsync();
GoogleUserData newUserData = JsonConvert.DeserializeObject<GoogleUserData>(outputData);
if (newUserData != null)
{
string file = Utils.GetDataStoreFolder() + newUserData.id;
string jsonFile = file + ".json";
string imageFile = file + ".png";
if (File.Exists(jsonFile))
{
string json = File.ReadAllText(jsonFile);
GoogleUserData existingUserData = JsonConvert.DeserializeObject<GoogleUserData>(json);
if (newUserData.picture != null &&
(!File.Exists(imageFile) ||
existingUserData.picture != null && existingUserData.picture != newUserData.picture))
Utils.GetImage(newUserData.picture, imageFile);
}
else
Utils.GetImage(newUserData.picture, imageFile);
// overwrites existing file
File.WriteAllText(jsonFile, outputData);
_userData = newUserData;
}
}
}
catch (Exception)
{
// return some rubbish for now.
_userData = new GoogleUserData() { id = "1234567890", name = "Unknown" };
}
}
public class GoogleUserData
{
public string id { get; set; }
public string name { get; set; }
public string picture { get; set; }
}
}
}