|
1 | 1 | using System; |
| 2 | +using System.Text; |
| 3 | +using System.Threading; |
| 4 | +using GitHub.Logging; |
2 | 5 |
|
3 | 6 | namespace GitHub.Unity |
4 | 7 | { |
5 | | - class AuthenticationService |
| 8 | + class AuthenticationService: IDisposable |
6 | 9 | { |
| 10 | + private readonly ITaskManager taskManager; |
| 11 | + private static readonly ILogging logger = LogHelper.GetLogger<AuthenticationService>(); |
| 12 | + |
7 | 13 | private readonly IApiClient client; |
8 | 14 |
|
9 | 15 | private LoginResult loginResultData; |
| 16 | + private IOAuthCallbackListener oauthCallbackListener; |
| 17 | + private CancellationTokenSource oauthCallbackCancellationToken; |
| 18 | + private string oauthCallbackState; |
10 | 19 |
|
11 | 20 | public AuthenticationService(UriString host, IKeychain keychain, |
12 | 21 | IProcessManager processManager, ITaskManager taskManager, |
13 | 22 | IEnvironment environment |
14 | 23 | ) |
15 | 24 | { |
| 25 | + this.taskManager = taskManager; |
16 | 26 | client = host == null |
17 | 27 | ? new ApiClient(keychain, processManager, taskManager, environment) |
18 | 28 | : new ApiClient(host, keychain, processManager, taskManager, environment); |
@@ -52,5 +62,74 @@ public void GetServerMeta(Action<GitHubHostMeta> serverMeta, Action<string> erro |
52 | 62 | error(exception.Message); |
53 | 63 | }); |
54 | 64 | } |
| 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 | + } |
55 | 134 | } |
56 | 135 | } |
0 commit comments