@@ -28,15 +28,15 @@ public AuthenticationPromptResult(AuthenticationModes mode)
28
28
AuthenticationMode = mode ;
29
29
}
30
30
31
- public AuthenticationPromptResult ( ICredential basicCredential )
32
- : this ( AuthenticationModes . Basic )
31
+ public AuthenticationPromptResult ( AuthenticationModes mode , ICredential credential )
32
+ : this ( mode )
33
33
{
34
- BasicCredential = basicCredential ;
34
+ Credential = credential ;
35
35
}
36
36
37
37
public AuthenticationModes AuthenticationMode { get ; }
38
38
39
- public ICredential BasicCredential { get ; set ; }
39
+ public ICredential Credential { get ; set ; }
40
40
}
41
41
42
42
[ Flags ]
@@ -45,6 +45,9 @@ public enum AuthenticationModes
45
45
None = 0 ,
46
46
Basic = 1 ,
47
47
OAuth = 1 << 1 ,
48
+ Pat = 1 << 2 ,
49
+
50
+ All = Basic | OAuth | Pat
48
51
}
49
52
50
53
public class GitHubAuthentication : AuthenticationBase , IGitHubAuthentication
@@ -63,16 +66,24 @@ public async Task<AuthenticationPromptResult> GetAuthenticationAsync(Uri targetU
63
66
64
67
if ( modes == AuthenticationModes . None )
65
68
{
66
- throw new ArgumentException ( $ "Must specify at least one { nameof ( AuthenticationModes ) } ", nameof ( modes ) ) ;
69
+ throw new ArgumentException ( @ $ "Must specify at least one { nameof ( AuthenticationModes ) } ", nameof ( modes ) ) ;
67
70
}
68
71
69
72
if ( TryFindHelperExecutablePath ( out string helperPath ) )
70
73
{
71
74
var promptArgs = new StringBuilder ( "prompt" ) ;
72
- if ( ( modes & AuthenticationModes . Basic ) != 0 ) promptArgs . Append ( " --basic" ) ;
73
- if ( ( modes & AuthenticationModes . OAuth ) != 0 ) promptArgs . Append ( " --oauth" ) ;
74
- if ( ! GitHubHostProvider . IsGitHubDotCom ( targetUri ) ) promptArgs . AppendFormat ( " --enterprise-url {0}" , targetUri ) ;
75
- if ( ! string . IsNullOrWhiteSpace ( userName ) ) promptArgs . AppendFormat ( " --username {0}" , userName ) ;
75
+ if ( modes == AuthenticationModes . All )
76
+ {
77
+ promptArgs . Append ( " --all" ) ;
78
+ }
79
+ else
80
+ {
81
+ if ( ( modes & AuthenticationModes . Basic ) != 0 ) promptArgs . Append ( " --basic" ) ;
82
+ if ( ( modes & AuthenticationModes . OAuth ) != 0 ) promptArgs . Append ( " --oauth" ) ;
83
+ if ( ( modes & AuthenticationModes . Pat ) != 0 ) promptArgs . Append ( " --pat" ) ;
84
+ }
85
+ if ( ! GitHubHostProvider . IsGitHubDotCom ( targetUri ) ) promptArgs . AppendFormat ( " --enterprise-url {0}" , QuoteCmdArg ( targetUri . ToString ( ) ) ) ;
86
+ if ( ! string . IsNullOrWhiteSpace ( userName ) ) promptArgs . AppendFormat ( " --username {0}" , QuoteCmdArg ( userName ) ) ;
76
87
77
88
IDictionary < string , string > resultDict = await InvokeHelperAsync ( helperPath , promptArgs . ToString ( ) , null ) ;
78
89
@@ -83,6 +94,15 @@ public async Task<AuthenticationPromptResult> GetAuthenticationAsync(Uri targetU
83
94
84
95
switch ( responseMode . ToLowerInvariant ( ) )
85
96
{
97
+ case "pat" :
98
+ if ( ! resultDict . TryGetValue ( "pat" , out string pat ) )
99
+ {
100
+ throw new Exception ( "Missing 'pat' in response" ) ;
101
+ }
102
+
103
+ return new AuthenticationPromptResult (
104
+ AuthenticationModes . Pat , new GitCredential ( userName , pat ) ) ;
105
+
86
106
case "oauth" :
87
107
return new AuthenticationPromptResult ( AuthenticationModes . OAuth ) ;
88
108
@@ -97,7 +117,8 @@ public async Task<AuthenticationPromptResult> GetAuthenticationAsync(Uri targetU
97
117
throw new Exception ( "Missing 'password' in response" ) ;
98
118
}
99
119
100
- return new AuthenticationPromptResult ( new GitCredential ( userName , password ) ) ;
120
+ return new AuthenticationPromptResult (
121
+ AuthenticationModes . Basic , new GitCredential ( userName , password ) ) ;
101
122
102
123
default :
103
124
throw new Exception ( $ "Unknown mode value in response '{ responseMode } '") ;
@@ -109,21 +130,6 @@ public async Task<AuthenticationPromptResult> GetAuthenticationAsync(Uri targetU
109
130
110
131
switch ( modes )
111
132
{
112
- case AuthenticationModes . Basic | AuthenticationModes . OAuth :
113
- var menuTitle = $ "Select an authentication method for '{ targetUri } '";
114
- var menu = new TerminalMenu ( Context . Terminal , menuTitle )
115
- {
116
- new TerminalMenuItem ( 1 , "Web browser" , isDefault : true ) ,
117
- new TerminalMenuItem ( 2 , "Username/password" )
118
- } ;
119
-
120
- int option = menu . Show ( ) ;
121
-
122
- if ( option == 1 ) goto case AuthenticationModes . OAuth ;
123
- if ( option == 2 ) goto case AuthenticationModes . Basic ;
124
-
125
- throw new Exception ( ) ;
126
-
127
133
case AuthenticationModes . Basic :
128
134
Context . Terminal . WriteLine ( "Enter GitHub credentials for '{0}'..." , targetUri ) ;
129
135
@@ -138,13 +144,41 @@ public async Task<AuthenticationPromptResult> GetAuthenticationAsync(Uri targetU
138
144
139
145
string password = Context . Terminal . PromptSecret ( "Password" ) ;
140
146
141
- return new AuthenticationPromptResult ( new GitCredential ( userName , password ) ) ;
147
+ return new AuthenticationPromptResult (
148
+ AuthenticationModes . Basic , new GitCredential ( userName , password ) ) ;
142
149
143
150
case AuthenticationModes . OAuth :
144
151
return new AuthenticationPromptResult ( AuthenticationModes . OAuth ) ;
145
152
153
+ case AuthenticationModes . Pat :
154
+ Context . Terminal . WriteLine ( "Enter GitHub personal access token for '{0}'..." , targetUri ) ;
155
+ string pat = Context . Terminal . PromptSecret ( "Token" ) ;
156
+ return new AuthenticationPromptResult (
157
+ AuthenticationModes . Pat , new GitCredential ( userName , pat ) ) ;
158
+
159
+ case AuthenticationModes . None :
160
+ throw new ArgumentOutOfRangeException ( nameof ( modes ) , @$ "At least one { nameof ( AuthenticationModes ) } must be supplied") ;
161
+
146
162
default :
147
- throw new ArgumentOutOfRangeException ( nameof ( modes ) , $ "Unknown { nameof ( AuthenticationModes ) } value") ;
163
+ var menuTitle = $ "Select an authentication method for '{ targetUri } '";
164
+ var menu = new TerminalMenu ( Context . Terminal , menuTitle ) ;
165
+
166
+ TerminalMenuItem oauthItem = null ;
167
+ TerminalMenuItem basicItem = null ;
168
+ TerminalMenuItem patItem = null ;
169
+
170
+ if ( ( modes & AuthenticationModes . OAuth ) != 0 ) oauthItem = menu . Add ( "Web browser" ) ;
171
+ if ( ( modes & AuthenticationModes . Pat ) != 0 ) patItem = menu . Add ( "Personal access token" ) ;
172
+ if ( ( modes & AuthenticationModes . Basic ) != 0 ) basicItem = menu . Add ( "Username/password" ) ;
173
+
174
+ // Default to the 'first' choice in the menu
175
+ TerminalMenuItem choice = menu . Show ( 0 ) ;
176
+
177
+ if ( choice == oauthItem ) goto case AuthenticationModes . OAuth ;
178
+ if ( choice == basicItem ) goto case AuthenticationModes . Basic ;
179
+ if ( choice == patItem ) goto case AuthenticationModes . Pat ;
180
+
181
+ throw new Exception ( ) ;
148
182
}
149
183
}
150
184
}
0 commit comments