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

Fix authentication again #873

Merged
merged 7 commits into from
Aug 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ _NCrunch_GitHub.Unity
.DS_Store
build/
TestResult.xml
submodules/
*.stackdump
*.lastcodeanalysissucceeded
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "script"]
path = script
url = git@github.com:github-for-unity/UnityBuildScripts
[submodule "submodules/packaging"]
path = submodules/packaging
url = https://github.com/github-for-unity/packaging
3 changes: 3 additions & 0 deletions create-octorun-zip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh -eu
DIR=$(pwd)
submodules/packaging/octorun/run.sh --path $DIR/octorun --out $DIR/src/GitHub.Api/Resources
4 changes: 2 additions & 2 deletions octorun/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ function ApiWrapper() {
throw "appName missing";
}

if (!config.user || !config.token) {
throw "user and/or token missing";
if (!config.token) {
throw "token missing";
}

this.octokit = octokitWrapper.createOctokit(config.appName);
Expand Down
1 change: 0 additions & 1 deletion octorun/src/authentication.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
var endOfLine = require('os').EOL;
var config = require("./configuration");
var octokitWrapper = require("./octokit");

Expand Down
1 change: 0 additions & 1 deletion octorun/src/bin/app-login.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
var commander = require("commander");
var package = require('../../package.json');
var authentication = require('../authentication');
var endOfLine = require('os').EOL;
var output = require('../output');

commander
Expand Down
1 change: 0 additions & 1 deletion octorun/src/bin/app-organizations.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
var commander = require("commander");
var package = require('../../package.json');
var ApiWrapper = require('../api');
var endOfLine = require('os').EOL;
var output = require('../output');

commander
Expand Down
1 change: 0 additions & 1 deletion octorun/src/bin/app-publish.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
var commander = require("commander");
var package = require('../../package.json')
var ApiWrapper = require('../api')
var endOfLine = require('os').EOL;
var output = require('../output');

commander
Expand Down
8 changes: 3 additions & 5 deletions octorun/src/bin/app-usage.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
var commander = require("commander");
var package = require('../../package.json')
var config = require("../configuration");
var endOfLine = require('os').EOL;
var commander = require('commander');
var package = require('../../package.json');
var config = require('../configuration');
var fs = require('fs');
var util = require('util');
var output = require('../output');

commander
Expand Down
1 change: 0 additions & 1 deletion octorun/src/bin/app-validate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var commander = require("commander");
var package = require('../../package.json');
var endOfLine = require('os').EOL;
var ApiWrapper = require('../api');
var output = require('../output');

Expand Down
2 changes: 0 additions & 2 deletions octorun/src/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ require("dotenv").config({silent: true});
var clientId = process.env.OCTOKIT_CLIENT_ID;
var clientSecret = process.env.OCTOKIT_CLIENT_SECRET;
var appName = process.env.OCTOKIT_USER_AGENT;
var user = process.env.OCTORUN_USER;
var token = process.env.OCTORUN_TOKEN;

module.exports = {
clientId: clientId,
clientSecret: clientSecret,
appName: appName,
user: user,
token: token
};
2 changes: 1 addition & 1 deletion octorun/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7f160da1
f497f7aa3d
2 changes: 1 addition & 1 deletion script
45 changes: 21 additions & 24 deletions src/GitHub.Api/Application/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,41 @@ class ApiClient : IApiClient
private readonly IKeychain keychain;
private readonly IProcessManager processManager;
private readonly ITaskManager taskManager;
private readonly NPath nodeJsExecutablePath;
private readonly NPath octorunScriptPath;
private readonly ILoginManager loginManager;
private readonly IEnvironment environment;

public ApiClient(UriString hostUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, NPath nodeJsExecutablePath, NPath octorunScriptPath)
public ApiClient(UriString hostUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, IEnvironment environment)
{
Guard.ArgumentNotNull(hostUrl, nameof(hostUrl));
Guard.ArgumentNotNull(keychain, nameof(keychain));

HostAddress = HostAddress.Create(hostUrl);
OriginalUrl = hostUrl;
var host = String.IsNullOrEmpty(hostUrl)
? UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri)
: new UriString(hostUrl.ToRepositoryUri()
.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));

HostAddress = HostAddress.Create(host);
OriginalUrl = host;
this.keychain = keychain;
this.processManager = processManager;
this.taskManager = taskManager;
this.nodeJsExecutablePath = nodeJsExecutablePath;
this.octorunScriptPath = octorunScriptPath;
loginManager = new LoginManager(keychain, processManager, taskManager, nodeJsExecutablePath, octorunScriptPath);
this.environment = environment;
loginManager = new LoginManager(keychain, processManager, taskManager, environment);
}

public ITask Logout(UriString host)
{
return loginManager.Logout(host);
}

public void CreateRepository(string name, string description, bool isPrivate, Action<GitHubRepository, Exception> callback, string organization = null)
public void CreateRepository(string name, string description, bool isPrivate,
Action<GitHubRepository, Exception> callback, string organization = null)
{
Guard.ArgumentNotNull(callback, "callback");

new FuncTask<GitHubRepository>(taskManager.Token, () =>
{
var user = GetCurrentUser();
var keychainAdapter = keychain.Connect(OriginalUrl);
// this validates the user, again
GetCurrentUser();

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

var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, command.ToString(),
user: user.Login, userToken: keychainAdapter.Credential.Token)
var octorunTask = new OctorunTask(taskManager.Token, keychain, environment, command.ToString())
.Configure(processManager);

var ret = octorunTask.RunSynchronously();
Expand Down Expand Up @@ -106,11 +108,8 @@ public void GetOrganizations(Action<Organization[]> onSuccess, Action<Exception>
Guard.ArgumentNotNull(onSuccess, nameof(onSuccess));
new FuncTask<Organization[]>(taskManager.Token, () =>
{
var user = GetCurrentUser();
var keychainAdapter = keychain.Connect(OriginalUrl);

var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, "organizations",
user: user.Login, userToken: keychainAdapter.Credential.Token)
var octorunTask = new OctorunTask(taskManager.Token, keychain, environment,
"organizations")
.Configure(processManager);

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

private GitHubUser GetCurrentUser()
{
//TODO: ONE_USER_LOGIN This assumes we only support one login
var keychainConnection = keychain.Connections.FirstOrDefault();
var keychainConnection = keychain.Connections.FirstOrDefault(x => x.Host == OriginalUrl);
if (keychainConnection == null)
throw new KeychainEmptyException();

Expand All @@ -227,7 +225,7 @@ private GitHubUser GetCurrentUser()

private IKeychainAdapter GetValidatedKeychainAdapter(Connection keychainConnection)
{
var keychainAdapter = keychain.Load(keychainConnection.Host);
var keychainAdapter = keychain.LoadFromSystem(keychainConnection.Host);
if (keychainAdapter == null)
throw new KeychainEmptyException();

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

var ret = octorunTask.RunSynchronously();
Expand Down
5 changes: 2 additions & 3 deletions src/GitHub.Api/Application/ApplicationManagerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ protected void Initialize()
#if ENABLE_METRICS
var metricsService = new MetricsService(ProcessManager,
TaskManager,
Environment.FileSystem,
Environment.NodeJsExecutablePath,
Environment.OctorunScriptPath);
Platform.Keychain,
Environment);
UsageTracker.MetricsService = metricsService;
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.Api/Authentication/Credential.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public Credential(UriString host, string username, string token)
this.Token = token;
}

public void UpdateToken(string token, string username)
public void Update(string token, string username)
{
this.Token = token;
this.Username = username;
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub.Api/Authentication/ICredentialManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public interface ICredential : IDisposable
UriString Host { get; }
string Username { get; }
string Token { get; }
void UpdateToken(string token, string username);
void Update(string token, string username);
}

public interface ICredentialManager
Expand Down
6 changes: 2 additions & 4 deletions src/GitHub.Api/Authentication/IKeychain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ namespace GitHub.Unity
public interface IKeychain
{
IKeychainAdapter Connect(UriString host);
IKeychainAdapter Load(UriString host);
IKeychainAdapter LoadFromSystem(UriString host);
void Clear(UriString host, bool deleteFromCredentialManager);
void Save(UriString host);
void SetCredentials(ICredential credential);
void SaveToSystem(UriString host);
void Initialize();
Connection[] Connections { get; }
IList<UriString> Hosts { get; }
bool HasKeys { get; }
void SetToken(UriString host, string token, string username);

event Action ConnectionsChanged;
}
Expand Down
48 changes: 17 additions & 31 deletions src/GitHub.Api/Authentication/Keychain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,32 +95,35 @@ public Keychain(IEnvironment environment, ICredentialManager credentialManager)
public IKeychainAdapter Connect(UriString host)
{
Guard.ArgumentNotNull(host, nameof(host));

return FindOrCreateAdapter(host);
}

public IKeychainAdapter Load(UriString host)
public IKeychainAdapter LoadFromSystem(UriString host)
{
Guard.ArgumentNotNull(host, nameof(host));

var keychainAdapter = FindOrCreateAdapter(host);
var connection = GetConnection(host);

var keychainItem = credentialManager.Load(host);
if (keychainItem == null)
var keychainAdapter = Connect(host) as KeychainAdapter;
var credential = credentialManager.Load(host);
if (credential == null)
{
logger.Warning("Cannot load host from Credential Manager; removing from cache");
Clear(host, false);
keychainAdapter = null;
}
else
{
if (keychainItem.Username != connection.Username)
keychainAdapter.Set(credential);
var connection = GetConnection(host);
if (connection.Username == null)
{
logger.Warning("Keychain Username:\"{0}\" does not match cached Username:\"{1}\"; Hopefully it works", keychainItem.Username, connection.Username);
connection.Username = credential.Username;
SaveConnectionsToDisk();
}

keychainAdapter.Set(keychainItem);
if (credential.Username != connection.Username)
{
logger.Warning("Keychain Username:\"{0}\" does not match cached Username:\"{1}\"; Hopefully it works", credential.Username, connection.Username);
}
}
return keychainAdapter;
}
Expand Down Expand Up @@ -151,32 +154,14 @@ public void Clear(UriString host, bool deleteFromCredentialManager)
RemoveCredential(host, deleteFromCredentialManager);
}

public void Save(UriString host)
public void SaveToSystem(UriString host)
{
Guard.ArgumentNotNull(host, nameof(host));

var keychainAdapter = AddCredential(host);
AddConnection(new Connection(host, keychainAdapter.Credential.Username));
}

public void SetCredentials(ICredential credential)
{
Guard.ArgumentNotNull(credential, nameof(credential));

var keychainAdapter = GetKeychainAdapter(credential.Host);
keychainAdapter.Set(credential);
}

public void SetToken(UriString host, string token, string username)
{
Guard.ArgumentNotNull(host, nameof(host));
Guard.ArgumentNotNull(token, nameof(token));
Guard.ArgumentNotNull(username, nameof(username));

var keychainAdapter = GetKeychainAdapter(host);
keychainAdapter.UpdateToken(token, username);
}

private void LoadConnectionsFromDisk()
{
if (cachePath.FileExists())
Expand Down Expand Up @@ -262,18 +247,19 @@ private void RemoveCredential(UriString host, bool deleteFromCredentialManager)
private Connection GetConnection(UriString host)
{
if (!connections.ContainsKey(host))
throw new ArgumentException($"{host} is not found", nameof(host));
return AddConnection(new Connection(host, null));
return connections[host];
}

private void AddConnection(Connection connection)
private Connection AddConnection(Connection connection)
{
// create new connection in the connection cache for this host
if (connections.ContainsKey(connection.Host))
connections[connection.Host] = connection;
else
connections.Add(connection.Host, connection);
SaveConnectionsToDisk();
return connection;
}

private void RemoveConnection(UriString host)
Expand Down
7 changes: 5 additions & 2 deletions src/GitHub.Api/Authentication/KeychainAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ public void Set(ICredential credential)
Credential = credential;
}

public void UpdateToken(string token, string username)
public void Update(string token, string username)
{
Credential.UpdateToken(token, username);
Credential.Update(token, username);
}

public void Clear()
Expand All @@ -23,5 +23,8 @@ public void Clear()
public interface IKeychainAdapter
{
ICredential Credential { get; }
void Set(ICredential credential);
void Update(string token, string username);
void Clear();
}
}
Loading