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

Commit a609e7a

Browse files
Functionality to login via link
1 parent a90431f commit a609e7a

File tree

11 files changed

+162
-7
lines changed

11 files changed

+162
-7
lines changed

Diff for: octorun/src/bin/app.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ commander
99
.command('organizations', 'Get Organizations')
1010
.command('publish', 'Publish')
1111
.command('usage', 'Usage')
12+
.command('token', 'Create OAuth Token')
1213
.command('meta', 'Get Server Meta Data')
1314
.parse(process.argv);

Diff for: octorun/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
902910f47
1+
902910f48

Diff for: src/GitHub.Api/Application/ApiClient.cs

+41-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Runtime.Serialization;
77
using System.Text;
88
using System.Text.RegularExpressions;
9+
using System.Threading;
910
using GitHub.Unity.Json;
1011

1112
namespace GitHub.Unity
@@ -14,6 +15,7 @@ class ApiClient : IApiClient
1415
{
1516
private static readonly ILogging logger = LogHelper.GetLogger<ApiClient>();
1617
private static readonly Regex httpStatusErrorRegex = new Regex("(?<=[a-z])([A-Z])", RegexOptions.Compiled);
18+
private static readonly Regex accessTokenRegex = new Regex("access_token=(.*?)&", RegexOptions.Compiled);
1719

1820
public HostAddress HostAddress { get; }
1921

@@ -25,7 +27,7 @@ class ApiClient : IApiClient
2527
private IKeychainAdapter keychainAdapter;
2628
private Connection connection;
2729

28-
public ApiClient(IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, IEnvironment environment):
30+
public ApiClient(IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, IEnvironment environment) :
2931
this(UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri), keychain, processManager, taskManager, environment)
3032
{
3133
}
@@ -277,6 +279,44 @@ public void LoginWithToken(string token, Action<bool> result)
277279
.Start();
278280
}
279281

282+
public void CreateOAuthToken(string code, Action<bool, string> result)
283+
{
284+
var command = "token -h " + HostAddress.WebUri.Host;
285+
var octorunTask = new OctorunTask(taskManager.Token, environment, command, code)
286+
.Configure(processManager);
287+
288+
octorunTask
289+
.Then((b, octorunResult) =>
290+
{
291+
if (b && octorunResult.IsSuccess)
292+
{
293+
var first = octorunResult.Output.FirstOrDefault();
294+
if (first == null)
295+
{
296+
result(false, "Error validating token.");
297+
return;
298+
}
299+
300+
var match = accessTokenRegex.Match(first);
301+
if (match.Success)
302+
{
303+
var token = match.Groups[1].Value;
304+
LoginWithToken(token, b1 => result(b1, "Error validating token."));
305+
}
306+
else
307+
{
308+
result(false, octorunResult.Output.FirstOrDefault());
309+
}
310+
}
311+
else
312+
{
313+
result(false, octorunResult.Output.FirstOrDefault());
314+
}
315+
})
316+
.Catch(exception => result(false, exception.ToString()))
317+
.Start();
318+
}
319+
280320
public void Login(string username, string password, Action<LoginResult> need2faCode, Action<bool, string> result)
281321
{
282322
Guard.ArgumentNotNull(need2faCode, "need2faCode");

Diff for: src/GitHub.Api/Application/IApiClient.cs

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ void CreateRepository(string name, string description, bool isPrivate,
1414
ITask Logout(UriString host);
1515
void GetCurrentUser(Action<GitHubUser> onSuccess, Action<Exception> onError = null);
1616
void GetEnterpriseServerMeta(Action<GitHubHostMeta> onSuccess, Action<Exception> onError = null);
17+
void CreateOAuthToken(string code, Action<bool, string> result);
1718
}
1819
}

Diff for: src/GitHub.Api/GitHub.Api.45.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@
6666
<Reference Include="System" />
6767
<Reference Include="System.Core" />
6868
<Reference Include="System.Threading" />
69+
<Reference Include="System.Web" />
6970
</ItemGroup>
7071
<ItemGroup>
7172
<Compile Include="Application\ApplicationInfo.cs" />
7273
<Compile Include="Application\LoginResult.cs" />
7374
<Compile Include="Application\ApplicationConfiguration.cs" />
7475
<Compile Include="Application\Organization.cs" />
76+
<Compile Include="Authentication\OAuthCallbackListener.cs" />
7577
<Compile Include="Cache\CacheContainer.cs" />
7678
<Compile Include="Cache\CacheInterfaces.cs" />
7779
<Compile Include="Cache\CachingClasses.cs" />

Diff for: src/GitHub.Api/GitHub.Api.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,14 @@
7777
<HintPath>$(SolutionDir).\packages\TaskParallelLibrary.1.0.3333.0\lib\Net35\System.Threading.dll</HintPath>
7878
<Private>True</Private>
7979
</Reference>
80+
<Reference Include="System.Web" />
8081
</ItemGroup>
8182
<ItemGroup>
8283
<Compile Include="Application\ApplicationInfo.cs" />
8384
<Compile Include="Application\LoginResult.cs" />
8485
<Compile Include="Application\ApplicationConfiguration.cs" />
8586
<Compile Include="Application\Organization.cs" />
87+
<Compile Include="Authentication\OAuthCallbackListener.cs" />
8688
<Compile Include="Cache\CacheContainer.cs" />
8789
<Compile Include="Cache\CacheInterfaces.cs" />
8890
<Compile Include="Cache\CachingClasses.cs" />

Diff for: src/GitHub.Api/Installer/OctorunInstaller.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public class OctorunInstallDetails
8686
public const string DefaultZipMd5Url = "http://github-vs.s3.amazonaws.com/unity/octorun/octorun.zip.md5";
8787
public const string DefaultZipUrl = "http://github-vs.s3.amazonaws.com/unity/octorun/octorun.zip";
8888

89-
public const string PackageVersion = "902910f47";
89+
public const string PackageVersion = "902910f48";
9090
private const string PackageName = "octorun";
9191
private const string zipFile = "octorun.zip";
9292

Diff for: src/GitHub.Api/Resources/octorun.zip

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:38edc11e8332150a2f642a7058980735477e8afd93e3b37faceee9f1fd00cf12
3-
size 220347
2+
oid sha256:2b38e3eb9c0178d67d0b33a8a2bc6118430b2d21b7ea7f8562a9cbf10b2df2f2
3+
size 221289

Diff for: src/GitHub.Api/Resources/octorun.zip.md5

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
977df0fef82ae85e55419b042b4078d7
1+
7e9bb4522ee6cc4d42ee10bd88f849a8

Diff for: src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs

+80-1
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
using System;
2+
using System.Text;
3+
using System.Threading;
4+
using GitHub.Logging;
25

36
namespace GitHub.Unity
47
{
5-
class AuthenticationService
8+
class AuthenticationService: IDisposable
69
{
10+
private readonly ITaskManager taskManager;
11+
private static readonly ILogging logger = LogHelper.GetLogger<AuthenticationService>();
12+
713
private readonly IApiClient client;
814

915
private LoginResult loginResultData;
16+
private IOAuthCallbackListener oauthCallbackListener;
17+
private CancellationTokenSource oauthCallbackCancellationToken;
18+
private string oauthCallbackState;
1019

1120
public AuthenticationService(UriString host, IKeychain keychain,
1221
IProcessManager processManager, ITaskManager taskManager,
1322
IEnvironment environment
1423
)
1524
{
25+
this.taskManager = taskManager;
1626
client = host == null
1727
? new ApiClient(keychain, processManager, taskManager, environment)
1828
: new ApiClient(host, keychain, processManager, taskManager, environment);
@@ -52,5 +62,74 @@ public void GetServerMeta(Action<GitHubHostMeta> serverMeta, Action<string> erro
5262
error(exception.Message);
5363
});
5464
}
65+
66+
public Uri StartOAuthListener(Action onSuccess, Action<string> onError)
67+
{
68+
if (oauthCallbackListener == null)
69+
{
70+
logger.Trace("Start OAuthCallbackListener");
71+
oauthCallbackListener = new OAuthCallbackListener();
72+
oauthCallbackCancellationToken = new CancellationTokenSource();
73+
74+
oauthCallbackState = Guid.NewGuid().ToString();
75+
oauthCallbackListener.Listen(
76+
oauthCallbackState,
77+
oauthCallbackCancellationToken.Token,
78+
code => {
79+
logger.Trace("OAuthCallbackListener Response: {0}", code);
80+
81+
client.CreateOAuthToken(code, (b, s) => {
82+
if (b)
83+
{
84+
onSuccess();
85+
}
86+
else
87+
{
88+
onError(s);
89+
}
90+
});
91+
});
92+
}
93+
94+
return GetLoginUrl(oauthCallbackState);
95+
}
96+
97+
public void StopOAuthListener()
98+
{
99+
if (oauthCallbackCancellationToken != null)
100+
{
101+
oauthCallbackCancellationToken.Cancel();
102+
}
103+
104+
oauthCallbackListener = null;
105+
oauthCallbackCancellationToken = null;
106+
}
107+
108+
private Uri GetLoginUrl(string state)
109+
{
110+
var query = new StringBuilder();
111+
112+
query.Append("client_id=");
113+
query.Append(Uri.EscapeDataString(ApplicationInfo.ClientId));
114+
query.Append("&redirect_uri=");
115+
query.Append(Uri.EscapeDataString("http://localhost:42424/callback"));
116+
query.Append("&scope=");
117+
query.Append(Uri.EscapeDataString("user,repo"));
118+
query.Append("&state=");
119+
query.Append(Uri.EscapeDataString(state));
120+
121+
var uri = new Uri(HostAddress.WebUri, "login/oauth/authorize");
122+
var uriBuilder = new UriBuilder(uri)
123+
{
124+
Query = query.ToString()
125+
};
126+
return uriBuilder.Uri;
127+
}
128+
129+
public void Dispose()
130+
{
131+
if (oauthCallbackCancellationToken != null)
132+
oauthCallbackCancellationToken.Dispose();
133+
}
55134
}
56135
}

Diff for: src/UnityExtension/Assets/Editor/GitHub.Unity/UI/GitHubAuthenticationView.cs

+30
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,40 @@ private void OnGUILogin()
145145
}
146146
}
147147
GUILayout.EndHorizontal();
148+
149+
GUILayout.Space(Styles.BaseSpacing + 3);
150+
GUILayout.BeginHorizontal();
151+
{
152+
GUILayout.FlexibleSpace();
153+
if (GUILayout.Button("Signin with your browser", Styles.HyperlinkStyle))
154+
{
155+
GUI.FocusControl(null);
156+
StartOAuthListener();
157+
}
158+
}
159+
GUILayout.EndHorizontal();
148160
}
149161
EditorGUI.EndDisabledGroup();
150162
}
151163

164+
private void StartOAuthListener()
165+
{
166+
try
167+
{
168+
var uri = AuthenticationService.StartOAuthListener(() => DoResult(true, null),
169+
s => {
170+
errorMessage = s;
171+
TaskManager.RunInUI(Redraw);
172+
});
173+
Application.OpenURL(uri.ToString());
174+
}
175+
catch (Exception ex)
176+
{
177+
errorMessage = ex.Message;
178+
Redraw();
179+
}
180+
}
181+
152182
private void OnGUI2FA()
153183
{
154184
GUILayout.BeginVertical();

0 commit comments

Comments
 (0)