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

Commit addbcf5

Browse files
StanleyGoldmanshana
authored andcommitted
Allow login with email (#690)
* Validating the authentication result in order to ensure that we have the username * Removing the UpdateToken method because it is never used * Making username required in SetToken * Centralize function to retrieve username * Getting username for regular logins as well * Removing unused fields * Making username required * Fixing unit test
1 parent 54a6411 commit addbcf5

File tree

8 files changed

+52
-42
lines changed

8 files changed

+52
-42
lines changed

src/GitHub.Api/Application/ApiClient.cs

Lines changed: 1 addition & 1 deletion
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,

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: 25 additions & 16 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,7 +72,8 @@ public async Task<LoginResultData> Login(
8472
throw new InvalidOperationException("Returned token is null or empty");
8573
}
8674

87-
keychain.SetToken(host, loginResultData.Token);
75+
username = await RetrieveUsername(loginResultData, username);
76+
keychain.SetToken(host, loginResultData.Token, username);
8877

8978
if (loginResultData.Code == LoginResultCodes.Success)
9079
{
@@ -123,7 +112,8 @@ public async Task<LoginResultData> ContinueLogin(LoginResultData loginResultData
123112
throw new InvalidOperationException("Returned token is null or empty");
124113
}
125114

126-
keychain.SetToken(host, loginResultData.Token);
115+
username = await RetrieveUsername(loginResultData, username);
116+
keychain.SetToken(host, loginResultData.Token, username);
127117
await keychain.Save(host);
128118

129119
return loginResultData;
@@ -199,6 +189,25 @@ private async Task<LoginResultData> TryLogin(
199189

200190
return new LoginResultData(LoginResultCodes.Failed, ret.GetApiErrorMessage() ?? "Failed.", host);
201191
}
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+
}
202211
}
203212

204213
class LoginResultData

src/tests/UnitTests/Authentication/KeychainTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ public void ShouldConnectSetCredentialsTokenAndSave()
292292
keychainAdapter.Credential.Username.Should().Be(username);
293293
keychainAdapter.Credential.Token.Should().Be(password);
294294

295-
keychain.SetToken(hostUri, token);
295+
keychain.SetToken(hostUri, token, username);
296296

297297
keychainAdapter.Credential.Should().NotBeNull();
298298
keychainAdapter.Credential.Host.Should().Be(hostUri);

0 commit comments

Comments
 (0)