1
- use async_trait:: async_trait;
2
-
3
1
use crate :: {
4
2
client:: { SetServiceResponse , Transport , TransportWithoutIO } ,
5
3
Protocol , Service ,
6
4
} ;
5
+ use async_trait:: async_trait;
7
6
8
- pub struct NativeSsh ;
7
+ mod client;
8
+ mod error;
9
+
10
+ pub use error:: Error ;
11
+
12
+ pub struct NativeSsh {
13
+ url : gix_url:: Url ,
14
+ desired_version : Protocol ,
15
+ trace : bool ,
16
+
17
+ identity : Option < gix_sec:: identity:: Account > ,
18
+ client : Option < client:: Client > ,
19
+ connection : Option < crate :: client:: git:: Connection < & ' static [ u8 ] , Vec < u8 > > > ,
20
+ }
9
21
10
22
impl TransportWithoutIO for NativeSsh {
23
+ fn set_identity ( & mut self , identity : gix_sec:: identity:: Account ) -> Result < ( ) , crate :: client:: Error > {
24
+ self . identity = Some ( identity) ;
25
+ Ok ( ( ) )
26
+ }
27
+
11
28
fn request (
12
29
& mut self ,
13
30
write_mode : crate :: client:: WriteMode ,
@@ -18,18 +35,18 @@ impl TransportWithoutIO for NativeSsh {
18
35
}
19
36
20
37
fn to_url ( & self ) -> std:: borrow:: Cow < ' _ , bstr:: BStr > {
21
- todo ! ( )
38
+ self . url . to_bstring ( ) . into ( )
22
39
}
23
40
24
41
fn connection_persists_across_multiple_requests ( & self ) -> bool {
25
- todo ! ( )
42
+ true
26
43
}
27
44
28
45
fn configure (
29
46
& mut self ,
30
47
config : & dyn std:: any:: Any ,
31
48
) -> Result < ( ) , Box < dyn std:: error:: Error + Send + Sync + ' static > > {
32
- todo ! ( )
49
+ Ok ( ( ) )
33
50
}
34
51
}
35
52
@@ -40,14 +57,59 @@ impl Transport for NativeSsh {
40
57
service : Service ,
41
58
extra_parameters : & ' a [ ( & ' a str , Option < & ' a str > ) ] ,
42
59
) -> Result < SetServiceResponse < ' _ > , crate :: client:: Error > {
43
- todo ! ( )
60
+ let host = self . url . host ( ) . expect ( "url has host" ) ;
61
+ let port = self . url . port_or_default ( ) . expect ( "ssh has a default port" ) ;
62
+
63
+ let auth_mode = match self . identity . as_ref ( ) {
64
+ Some ( crate :: client:: Account {
65
+ username,
66
+ password,
67
+ oauth_refresh_token : _,
68
+ } ) => client:: AuthMode :: UsernamePassword {
69
+ username : username. clone ( ) ,
70
+ password : password. clone ( ) ,
71
+ } ,
72
+ None => return Err ( crate :: client:: Error :: AuthenticationUnsupported ) ,
73
+ } ;
74
+
75
+ let client = client:: Client :: connect ( host, port, auth_mode) . await ?;
76
+
77
+ let connection = crate :: client:: git:: Connection :: new (
78
+ [ 0u8 ] . as_slice ( ) , // TODO
79
+ vec ! [ ] , // TODO
80
+ self . desired_version ,
81
+ self . url . path . clone ( ) ,
82
+ None :: < ( String , _ ) > ,
83
+ crate :: client:: git:: ConnectMode :: Process ,
84
+ self . trace ,
85
+ ) ;
86
+
87
+ self . client = Some ( client) ;
88
+ self . connection = Some ( connection) ;
89
+
90
+ self . connection
91
+ . as_mut ( )
92
+ . expect ( "connection to be there right after setting it" )
93
+ . handshake ( service, extra_parameters)
94
+ . await
44
95
}
45
96
}
46
97
98
+ #[ allow( clippy:: unused_async) ]
47
99
pub async fn connect (
48
100
url : gix_url:: Url ,
49
101
desired_version : Protocol ,
50
102
trace : bool ,
51
- ) -> Result < NativeSsh , crate :: client:: Error > {
52
- todo ! ( )
103
+ ) -> Result < NativeSsh , crate :: client:: connect:: Error > {
104
+ if url. scheme != gix_url:: Scheme :: Ssh {
105
+ return Err ( crate :: client:: connect:: Error :: UnsupportedScheme ( url. scheme ) ) ;
106
+ }
107
+ Ok ( NativeSsh {
108
+ url,
109
+ desired_version,
110
+ trace,
111
+ identity : None ,
112
+ client : None ,
113
+ connection : None ,
114
+ } )
53
115
}
0 commit comments