Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit 4addc6c

Browse files
Merge branch 'master' into enhancements/more-metrics
2 parents 6247541 + 4d09872 commit 4addc6c

File tree

14 files changed

+107
-120
lines changed

14 files changed

+107
-120
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ _NCrunch_GitHub.Unity
66
.DS_Store
77
build/
88
TestResult.xml
9-
submodules/
9+
submodules/
10+
*.stackdump

common/SolutionInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@
3131
namespace System
3232
{
3333
internal static class AssemblyVersionInformation {
34-
internal const string Version = "0.31.8";
34+
internal const string Version = "0.32.0";
3535
}
3636
}

src/GitHub.Api/Application/ApiClient.cs

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public ApiClient(UriString hostUrl, IKeychain keychain, IProcessManager processM
3333
this.taskManager = taskManager;
3434
this.nodeJsExecutablePath = nodeJsExecutablePath;
3535
this.octorunScriptPath = octorunScriptPath;
36-
loginManager = new LoginManager(keychain, ApplicationInfo.ClientId, ApplicationInfo.ClientSecret,
36+
loginManager = new LoginManager(keychain,
3737
processManager: processManager,
3838
taskManager: taskManager,
3939
nodeJsExecutablePath: nodeJsExecutablePath,
@@ -131,55 +131,6 @@ public async Task ContinueLogin(LoginResult loginResult, string code)
131131
loginResult.Callback(result.Code == LoginResultCodes.Success, result.Message);
132132
}
133133

134-
public async Task<bool> LoginAsync(string username, string password, Func<LoginResult, string> need2faCode)
135-
{
136-
Guard.ArgumentNotNull(need2faCode, "need2faCode");
137-
138-
LoginResultData res = null;
139-
try
140-
{
141-
res = await loginManager.Login(OriginalUrl, username, password);
142-
}
143-
catch (Exception)
144-
{
145-
return false;
146-
}
147-
148-
if (res.Code == LoginResultCodes.CodeRequired)
149-
{
150-
var resultCache = new LoginResult(res, null, null);
151-
var code = need2faCode(resultCache);
152-
return await ContinueLoginAsync(resultCache, need2faCode, code);
153-
}
154-
else
155-
{
156-
return res.Code == LoginResultCodes.Success;
157-
}
158-
}
159-
160-
public async Task<bool> ContinueLoginAsync(LoginResult loginResult, Func<LoginResult, string> need2faCode, string code)
161-
{
162-
LoginResultData result = null;
163-
try
164-
{
165-
result = await loginManager.ContinueLogin(loginResult.Data, code);
166-
}
167-
catch (Exception)
168-
{
169-
return false;
170-
}
171-
172-
if (result.Code == LoginResultCodes.CodeFailed)
173-
{
174-
var resultCache = new LoginResult(result, null, null);
175-
code = need2faCode(resultCache);
176-
if (String.IsNullOrEmpty(code))
177-
return false;
178-
return await ContinueLoginAsync(resultCache, need2faCode, code);
179-
}
180-
return result.Code == LoginResultCodes.Success;
181-
}
182-
183134
private async Task<GitHubUser> GetCurrentUser()
184135
{
185136
//TODO: ONE_USER_LOGIN This assumes we only support one login

src/GitHub.Api/Application/IApiClient.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Task CreateRepository(string name, string description, bool isPrivate,
1212
Task GetOrganizations(Action<Organization[]> onSuccess, Action<Exception> onError = null);
1313
Task Login(string username, string password, Action<LoginResult> need2faCode, Action<bool, string> result);
1414
Task ContinueLogin(LoginResult loginResult, string code);
15-
Task<bool> LoginAsync(string username, string password, Func<LoginResult, string> need2faCode);
1615
Task Logout(UriString host);
1716
Task GetCurrentUser(Action<GitHubUser> onSuccess, Action<Exception> onError = null);
1817
}

src/GitHub.Api/Authentication/Credential.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ public Credential(UriString host, string username, string token)
1616
this.Token = token;
1717
}
1818

19-
public void UpdateToken(string token)
19+
public void UpdateToken(string token, string username)
2020
{
2121
this.Token = token;
22+
this.Username = username;
2223
}
2324

2425
public UriString Host { get; private set; }

src/GitHub.Api/Authentication/ICredentialManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public interface ICredential : IDisposable
88
UriString Host { get; }
99
string Username { get; }
1010
string Token { get; }
11-
void UpdateToken(string token);
11+
void UpdateToken(string token, string username);
1212
}
1313

1414
public interface ICredentialManager

src/GitHub.Api/Authentication/IKeychain.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ public interface IKeychain
1010
Task<IKeychainAdapter> Load(UriString host);
1111
Task Clear(UriString host, bool deleteFromCredentialManager);
1212
Task Save(UriString host);
13-
void UpdateToken(UriString host, string token);
1413
void SetCredentials(ICredential credential);
1514
void Initialize();
1615
Connection[] Connections { get; }
1716
IList<UriString> Hosts { get; }
1817
bool HasKeys { get; }
19-
void SetToken(UriString host, string token);
18+
void SetToken(UriString host, string token, string username);
2019

2120
event Action ConnectionsChanged;
2221
}

src/GitHub.Api/Authentication/Keychain.cs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,15 @@ public Keychain(IEnvironment environment, ICredentialManager credentialManager)
9595

9696
public IKeychainAdapter Connect(UriString host)
9797
{
98+
Guard.ArgumentNotNull(host, nameof(host));
99+
98100
return FindOrCreateAdapter(host);
99101
}
100102

101103
public async Task<IKeychainAdapter> Load(UriString host)
102104
{
105+
Guard.ArgumentNotNull(host, nameof(host));
106+
103107
var keychainAdapter = FindOrCreateAdapter(host);
104108
var connection = GetConnection(host);
105109

@@ -145,6 +149,9 @@ public void Initialize()
145149
public async Task Clear(UriString host, bool deleteFromCredentialManager)
146150
{
147151
//logger.Trace("Clear Host:{0}", host);
152+
153+
Guard.ArgumentNotNull(host, nameof(host));
154+
148155
//clear octokit credentials
149156
await RemoveCredential(host, deleteFromCredentialManager);
150157
RemoveConnection(host);
@@ -153,30 +160,33 @@ public async Task Clear(UriString host, bool deleteFromCredentialManager)
153160
public async Task Save(UriString host)
154161
{
155162
//logger.Trace("Save: {0}", host);
163+
164+
Guard.ArgumentNotNull(host, nameof(host));
165+
156166
var keychainAdapter = await AddCredential(host);
157167
AddConnection(new Connection(host, keychainAdapter.Credential.Username));
158168
}
159169

160170
public void SetCredentials(ICredential credential)
161171
{
162172
//logger.Trace("SetCredentials Host:{0}", credential.Host);
173+
174+
Guard.ArgumentNotNull(credential, nameof(credential));
175+
163176
var keychainAdapter = GetKeychainAdapter(credential.Host);
164177
keychainAdapter.Set(credential);
165178
}
166179

167-
public void SetToken(UriString host, string token)
180+
public void SetToken(UriString host, string token, string username)
168181
{
169182
//logger.Trace("SetToken Host:{0}", host);
170-
var keychainAdapter = GetKeychainAdapter(host);
171-
keychainAdapter.UpdateToken(token);
172-
}
173183

174-
public void UpdateToken(UriString host, string token)
175-
{
176-
//logger.Trace("UpdateToken Host:{0}", host);
184+
Guard.ArgumentNotNull(host, nameof(host));
185+
Guard.ArgumentNotNull(token, nameof(token));
186+
Guard.ArgumentNotNull(username, nameof(username));
187+
177188
var keychainAdapter = GetKeychainAdapter(host);
178-
var keychainItem = keychainAdapter.Credential;
179-
keychainItem.UpdateToken(token);
189+
keychainAdapter.UpdateToken(token, username);
180190
}
181191

182192
private void LoadConnectionsFromDisk()
@@ -290,15 +300,6 @@ private void RemoveConnection(UriString host)
290300
}
291301
}
292302

293-
private void RemoveAllConnections()
294-
{
295-
if (connections.Count > 0)
296-
{
297-
connections.Clear();
298-
SaveConnectionsToDisk();
299-
}
300-
}
301-
302303
private void UpdateConnections(Connection[] conns)
303304
{
304305
var updated = false;

src/GitHub.Api/Authentication/KeychainAdapter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ public void Set(ICredential credential)
99
Credential = credential;
1010
}
1111

12-
public void UpdateToken(string token)
12+
public void UpdateToken(string token, string username)
1313
{
14-
Credential.UpdateToken(token);
14+
Credential.UpdateToken(token, username);
1515
}
1616

1717
public void Clear()

src/GitHub.Api/Authentication/LoginManager.cs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using System;
2-
using System.Linq;
3-
using System.Net;
42
using System.Threading.Tasks;
53
using GitHub.Logging;
64

@@ -23,8 +21,6 @@ class LoginManager : ILoginManager
2321
private readonly ILogging logger = LogHelper.GetLogger<LoginManager>();
2422

2523
private readonly IKeychain keychain;
26-
private readonly string clientId;
27-
private readonly string clientSecret;
2824
private readonly IProcessManager processManager;
2925
private readonly ITaskManager taskManager;
3026
private readonly NPath? nodeJsExecutablePath;
@@ -34,25 +30,17 @@ class LoginManager : ILoginManager
3430
/// Initializes a new instance of the <see cref="LoginManager"/> class.
3531
/// </summary>
3632
/// <param name="keychain"></param>
37-
/// <param name="clientId">The application's client API ID.</param>
38-
/// <param name="clientSecret">The application's client API secret.</param>
3933
/// <param name="processManager"></param>
4034
/// <param name="taskManager"></param>
4135
/// <param name="nodeJsExecutablePath"></param>
4236
/// <param name="octorunScript"></param>
4337
public LoginManager(
44-
IKeychain keychain,
45-
string clientId,
46-
string clientSecret,
47-
IProcessManager processManager = null, ITaskManager taskManager = null, NPath? nodeJsExecutablePath = null, NPath? octorunScript = null)
38+
IKeychain keychain, IProcessManager processManager = null, ITaskManager taskManager = null,
39+
NPath? nodeJsExecutablePath = null, NPath? octorunScript = null)
4840
{
4941
Guard.ArgumentNotNull(keychain, nameof(keychain));
50-
Guard.ArgumentNotNullOrWhiteSpace(clientId, nameof(clientId));
51-
Guard.ArgumentNotNullOrWhiteSpace(clientSecret, nameof(clientSecret));
5242

5343
this.keychain = keychain;
54-
this.clientId = clientId;
55-
this.clientSecret = clientSecret;
5644
this.processManager = processManager;
5745
this.taskManager = taskManager;
5846
this.nodeJsExecutablePath = nodeJsExecutablePath;
@@ -84,8 +72,13 @@ public async Task<LoginResultData> Login(
8472
throw new InvalidOperationException("Returned token is null or empty");
8573
}
8674

87-
keychain.SetToken(host, loginResultData.Token);
88-
await keychain.Save(host);
75+
username = await RetrieveUsername(loginResultData, username);
76+
keychain.SetToken(host, loginResultData.Token, username);
77+
78+
if (loginResultData.Code == LoginResultCodes.Success)
79+
{
80+
await keychain.Save(host);
81+
}
8982

9083
return loginResultData;
9184
}
@@ -119,7 +112,8 @@ public async Task<LoginResultData> ContinueLogin(LoginResultData loginResultData
119112
throw new InvalidOperationException("Returned token is null or empty");
120113
}
121114

122-
keychain.SetToken(host, loginResultData.Token);
115+
username = await RetrieveUsername(loginResultData, username);
116+
keychain.SetToken(host, loginResultData.Token, username);
123117
await keychain.Save(host);
124118

125119
return loginResultData;
@@ -195,6 +189,25 @@ private async Task<LoginResultData> TryLogin(
195189

196190
return new LoginResultData(LoginResultCodes.Failed, ret.GetApiErrorMessage() ?? "Failed.", host);
197191
}
192+
193+
private async Task<string> RetrieveUsername(LoginResultData loginResultData, string username)
194+
{
195+
if (!username.Contains("@"))
196+
{
197+
return username;
198+
}
199+
200+
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath.Value, octorunScript.Value, "validate",
201+
user: username, userToken: loginResultData.Token).Configure(processManager);
202+
203+
var validateResult = await octorunTask.StartAsAsync();
204+
if (!validateResult.IsSuccess)
205+
{
206+
throw new InvalidOperationException("Authentication validation failed");
207+
}
208+
209+
return validateResult.Output[1];
210+
}
198211
}
199212

200213
class LoginResultData

0 commit comments

Comments
 (0)