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

Commit f497f7a

Browse files
committed
Fix authentication, again
Fix signin/signout not available if there's no repo. Fix signout of the active connection. Fix mismatches between what's in the connections file to what we're trying to signout or load the keychain for.
1 parent 84405f2 commit f497f7a

25 files changed

+137
-166
lines changed

octorun/src/api.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ function ApiWrapper() {
66
throw "appName missing";
77
}
88

9-
if (!config.user || !config.token) {
10-
throw "user and/or token missing";
9+
if (!config.token) {
10+
throw "token missing";
1111
}
1212

1313
this.octokit = octokitWrapper.createOctokit(config.appName);

octorun/src/authentication.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
var endOfLine = require('os').EOL;
21
var config = require("./configuration");
32
var octokitWrapper = require("./octokit");
43

octorun/src/bin/app-login.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
var commander = require("commander");
22
var package = require('../../package.json');
33
var authentication = require('../authentication');
4-
var endOfLine = require('os').EOL;
54
var output = require('../output');
65

76
commander

octorun/src/bin/app-organizations.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
var commander = require("commander");
22
var package = require('../../package.json');
33
var ApiWrapper = require('../api');
4-
var endOfLine = require('os').EOL;
54
var output = require('../output');
65

76
commander

octorun/src/bin/app-publish.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
var commander = require("commander");
22
var package = require('../../package.json')
33
var ApiWrapper = require('../api')
4-
var endOfLine = require('os').EOL;
54
var output = require('../output');
65

76
commander

octorun/src/bin/app-usage.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
var commander = require("commander");
2-
var package = require('../../package.json')
3-
var config = require("../configuration");
4-
var endOfLine = require('os').EOL;
1+
var commander = require('commander');
2+
var package = require('../../package.json');
3+
var config = require('../configuration');
54
var fs = require('fs');
6-
var util = require('util');
75
var output = require('../output');
86

97
commander

octorun/src/bin/app-validate.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
var commander = require("commander");
22
var package = require('../../package.json');
3-
var endOfLine = require('os').EOL;
43
var ApiWrapper = require('../api');
54
var output = require('../output');
65

octorun/src/configuration.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ require("dotenv").config({silent: true});
33
var clientId = process.env.OCTOKIT_CLIENT_ID;
44
var clientSecret = process.env.OCTOKIT_CLIENT_SECRET;
55
var appName = process.env.OCTOKIT_USER_AGENT;
6-
var user = process.env.OCTORUN_USER;
76
var token = process.env.OCTORUN_TOKEN;
87

98
module.exports = {
109
clientId: clientId,
1110
clientSecret: clientSecret,
1211
appName: appName,
13-
user: user,
1412
token: token
1513
};

script

src/GitHub.Api/Application/ApiClient.cs

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,41 @@ class ApiClient : IApiClient
1616
private readonly IKeychain keychain;
1717
private readonly IProcessManager processManager;
1818
private readonly ITaskManager taskManager;
19-
private readonly NPath nodeJsExecutablePath;
20-
private readonly NPath octorunScriptPath;
2119
private readonly ILoginManager loginManager;
20+
private readonly IEnvironment environment;
2221

23-
public ApiClient(UriString hostUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, NPath nodeJsExecutablePath, NPath octorunScriptPath)
22+
public ApiClient(UriString hostUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, IEnvironment environment)
2423
{
25-
Guard.ArgumentNotNull(hostUrl, nameof(hostUrl));
2624
Guard.ArgumentNotNull(keychain, nameof(keychain));
2725

28-
HostAddress = HostAddress.Create(hostUrl);
29-
OriginalUrl = hostUrl;
26+
var host = String.IsNullOrEmpty(hostUrl)
27+
? UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri)
28+
: new UriString(hostUrl.ToRepositoryUri()
29+
.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));
30+
31+
HostAddress = HostAddress.Create(host);
32+
OriginalUrl = host;
3033
this.keychain = keychain;
3134
this.processManager = processManager;
3235
this.taskManager = taskManager;
33-
this.nodeJsExecutablePath = nodeJsExecutablePath;
34-
this.octorunScriptPath = octorunScriptPath;
35-
loginManager = new LoginManager(keychain, processManager, taskManager, nodeJsExecutablePath, octorunScriptPath);
36+
this.environment = environment;
37+
loginManager = new LoginManager(keychain, processManager, taskManager, environment);
3638
}
3739

3840
public ITask Logout(UriString host)
3941
{
4042
return loginManager.Logout(host);
4143
}
4244

43-
public void CreateRepository(string name, string description, bool isPrivate, Action<GitHubRepository, Exception> callback, string organization = null)
45+
public void CreateRepository(string name, string description, bool isPrivate,
46+
Action<GitHubRepository, Exception> callback, string organization = null)
4447
{
4548
Guard.ArgumentNotNull(callback, "callback");
4649

4750
new FuncTask<GitHubRepository>(taskManager.Token, () =>
4851
{
49-
var user = GetCurrentUser();
50-
var keychainAdapter = keychain.Connect(OriginalUrl);
52+
// this validates the user, again
53+
GetCurrentUser();
5154

5255
var command = new StringBuilder("publish -r \"");
5356
command.Append(name);
@@ -72,8 +75,7 @@ public void CreateRepository(string name, string description, bool isPrivate, Ac
7275
command.Append(" -p");
7376
}
7477

75-
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, command.ToString(),
76-
user: user.Login, userToken: keychainAdapter.Credential.Token)
78+
var octorunTask = new OctorunTask(taskManager.Token, keychain, environment, command.ToString())
7779
.Configure(processManager);
7880

7981
var ret = octorunTask.RunSynchronously();
@@ -106,11 +108,8 @@ public void GetOrganizations(Action<Organization[]> onSuccess, Action<Exception>
106108
Guard.ArgumentNotNull(onSuccess, nameof(onSuccess));
107109
new FuncTask<Organization[]>(taskManager.Token, () =>
108110
{
109-
var user = GetCurrentUser();
110-
var keychainAdapter = keychain.Connect(OriginalUrl);
111-
112-
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, "organizations",
113-
user: user.Login, userToken: keychainAdapter.Credential.Token)
111+
var octorunTask = new OctorunTask(taskManager.Token, keychain, environment,
112+
"organizations")
114113
.Configure(processManager);
115114

116115
var ret = octorunTask.RunSynchronously();
@@ -208,8 +207,7 @@ public void ContinueLogin(LoginResult loginResult, string code)
208207

209208
private GitHubUser GetCurrentUser()
210209
{
211-
//TODO: ONE_USER_LOGIN This assumes we only support one login
212-
var keychainConnection = keychain.Connections.FirstOrDefault();
210+
var keychainConnection = keychain.Connections.FirstOrDefault(x => x.Host == OriginalUrl);
213211
if (keychainConnection == null)
214212
throw new KeychainEmptyException();
215213

@@ -249,8 +247,7 @@ private GitHubUser GetValidatedGitHubUser(Connection keychainConnection, IKeycha
249247
{
250248
try
251249
{
252-
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, "validate",
253-
user: keychainConnection.Username, userToken: keychainAdapter.Credential.Token)
250+
var octorunTask = new OctorunTask(taskManager.Token, keychain, environment, "validate")
254251
.Configure(processManager);
255252

256253
var ret = octorunTask.RunSynchronously();

src/GitHub.Api/Application/ApplicationManagerBase.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,8 @@ protected void Initialize()
5353
#if ENABLE_METRICS
5454
var metricsService = new MetricsService(ProcessManager,
5555
TaskManager,
56-
Environment.FileSystem,
57-
Environment.NodeJsExecutablePath,
58-
Environment.OctorunScriptPath);
56+
Platform.Keychain,
57+
Environment);
5958
UsageTracker.MetricsService = metricsService;
6059
#endif
6160
}

src/GitHub.Api/Authentication/IKeychain.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace GitHub.Unity
66
public interface IKeychain
77
{
88
IKeychainAdapter Connect(UriString host);
9-
IKeychainAdapter Load(UriString host);
9+
IKeychainAdapter Load(UriString host, bool dontClear = false);
1010
void Clear(UriString host, bool deleteFromCredentialManager);
1111
void Save(UriString host);
1212
void SetCredentials(ICredential credential);

src/GitHub.Api/Authentication/Keychain.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,30 @@ public IKeychainAdapter Connect(UriString host)
9999
return FindOrCreateAdapter(host);
100100
}
101101

102-
public IKeychainAdapter Load(UriString host)
102+
public IKeychainAdapter Load(UriString host, bool dontClear = false)
103103
{
104104
Guard.ArgumentNotNull(host, nameof(host));
105105

106-
var keychainAdapter = FindOrCreateAdapter(host);
107-
var connection = GetConnection(host);
108-
106+
var keychainAdapter = Connect(host) as KeychainAdapter;
109107
var keychainItem = credentialManager.Load(host);
110108
if (keychainItem == null)
111109
{
112-
logger.Warning("Cannot load host from Credential Manager; removing from cache");
113-
Clear(host, false);
110+
if (!dontClear)
111+
{
112+
logger.Warning("Cannot load host from Credential Manager; removing from cache");
113+
Clear(host, false);
114+
}
114115
keychainAdapter = null;
115116
}
116117
else
117118
{
119+
var connection = GetConnection(host);
120+
if (connection.Username == null)
121+
{
122+
connection.Username = keychainItem.Username;
123+
SaveConnectionsToDisk();
124+
}
125+
118126
if (keychainItem.Username != connection.Username)
119127
{
120128
logger.Warning("Keychain Username:\"{0}\" does not match cached Username:\"{1}\"; Hopefully it works", keychainItem.Username, connection.Username);
@@ -262,18 +270,19 @@ private void RemoveCredential(UriString host, bool deleteFromCredentialManager)
262270
private Connection GetConnection(UriString host)
263271
{
264272
if (!connections.ContainsKey(host))
265-
throw new ArgumentException($"{host} is not found", nameof(host));
273+
return AddConnection(new Connection(host, null));
266274
return connections[host];
267275
}
268276

269-
private void AddConnection(Connection connection)
277+
private Connection AddConnection(Connection connection)
270278
{
271279
// create new connection in the connection cache for this host
272280
if (connections.ContainsKey(connection.Host))
273281
connections[connection.Host] = connection;
274282
else
275283
connections.Add(connection.Host, connection);
276284
SaveConnectionsToDisk();
285+
return connection;
277286
}
278287

279288
private void RemoveConnection(UriString host)

src/GitHub.Api/Authentication/LoginManager.cs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ class LoginManager : ILoginManager
2222
private readonly IKeychain keychain;
2323
private readonly IProcessManager processManager;
2424
private readonly ITaskManager taskManager;
25-
private readonly NPath? nodeJsExecutablePath;
26-
private readonly NPath? octorunScript;
25+
private readonly IEnvironment environment;
2726

2827
/// <summary>
2928
/// Initializes a new instance of the <see cref="LoginManager"/> class.
@@ -35,15 +34,14 @@ class LoginManager : ILoginManager
3534
/// <param name="octorunScript"></param>
3635
public LoginManager(
3736
IKeychain keychain, IProcessManager processManager, ITaskManager taskManager,
38-
NPath? nodeJsExecutablePath = null, NPath? octorunScript = null)
37+
IEnvironment environment)
3938
{
4039
Guard.ArgumentNotNull(keychain, nameof(keychain));
4140

4241
this.keychain = keychain;
4342
this.processManager = processManager;
4443
this.taskManager = taskManager;
45-
this.nodeJsExecutablePath = nodeJsExecutablePath;
46-
this.octorunScript = octorunScript;
44+
this.environment = environment;
4745
}
4846

4947
/// <inheritdoc/>
@@ -146,22 +144,12 @@ private LoginResultData TryLogin(
146144
string code = null
147145
)
148146
{
149-
if (!nodeJsExecutablePath.HasValue)
150-
{
151-
throw new InvalidOperationException("nodeJsExecutablePath must be set");
152-
}
153-
154-
if (!octorunScript.HasValue)
155-
{
156-
throw new InvalidOperationException("octorunScript must be set");
157-
}
158-
159147
var hasTwoFactorCode = code != null;
160148

161149
var arguments = hasTwoFactorCode ? "login --twoFactor" : "login";
162-
var loginTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath.Value, octorunScript.Value,
163-
arguments, ApplicationInfo.ClientId, ApplicationInfo.ClientSecret);
164-
loginTask.Configure(processManager, workingDirectory: octorunScript.Value.Parent.Parent, withInput: true);
150+
var loginTask = new OctorunTask(taskManager.Token, keychain, environment,
151+
arguments);
152+
loginTask.Configure(processManager, withInput: true);
165153
loginTask.OnStartProcess += proc =>
166154
{
167155
proc.StandardInput.WriteLine(username);
@@ -198,8 +186,8 @@ private string RetrieveUsername(LoginResultData loginResultData, string username
198186
return username;
199187
}
200188

201-
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath.Value, octorunScript.Value, "validate",
202-
user: username, userToken: loginResultData.Token).Configure(processManager);
189+
var octorunTask = new OctorunTask(taskManager.Token, keychain, environment, "validate")
190+
.Configure(processManager);
203191

204192
var validateResult = octorunTask.RunSynchronously();
205193
if (!validateResult.IsSuccess)

src/GitHub.Api/Git/GitCredentialManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public ICredential Load(UriString host)
6060

6161
if (String.IsNullOrEmpty(kvpCreds))
6262
{
63-
Logger.Error("No credentials are stored");
63+
// we didn't find credentials, stop here
6464
return null;
6565
}
6666

src/GitHub.Api/Primitives/UriString.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public class UriString : StringEquivalent<UriString>, IEquatable<UriString>
2828
public UriString(string uriString) : base(NormalizePath(uriString))
2929
{
3030
if (uriString == null || uriString.Length == 0) return;
31-
if (Uri.TryCreate(uriString, UriKind.Absolute, out url))
31+
if (Uri.TryCreate(uriString, UriKind.Absolute, out url)
32+
|| Uri.TryCreate("https://" + uriString, UriKind.Absolute, out url))
3233
{
3334
if (!url.IsFile)
3435
SetUri(url);

0 commit comments

Comments
 (0)