@@ -7,7 +7,6 @@ use crate::response::{Course, CourseDetails, Organization};
77use crate :: { Language , RunResult , ValidationResult } ;
88
99use oauth2:: basic:: BasicClient ;
10- use oauth2:: prelude:: * ;
1110use oauth2:: {
1211 AuthUrl , ClientId , ClientSecret , ResourceOwnerPassword , ResourceOwnerUsername , TokenUrl ,
1312} ;
@@ -18,7 +17,6 @@ use std::path::Path;
1817use std:: path:: PathBuf ;
1918use tempfile:: NamedTempFile ;
2019use tmc_langs_util:: task_executor;
21- use url1:: Url as Url1 ;
2220
2321pub type Token =
2422 oauth2:: StandardTokenResponse < oauth2:: EmptyExtraTokenFields , oauth2:: basic:: BasicTokenType > ;
@@ -42,7 +40,10 @@ impl TmcCore {
4240 ///
4341 /// # Examples
4442 /// ```rust,no_run
45- /// let core = TmcCore::new(Path::new("./config"), "https://tmc.mooc.fi".to_string()).unwrap();
43+ /// use tmc_langs_core::TmcCore;
44+ /// use std::path::PathBuf;
45+ ///
46+ /// let core = TmcCore::new(PathBuf::from("./config"), "https://tmc.mooc.fi".to_string()).unwrap();
4647 /// ```
4748 pub fn new ( config_dir : PathBuf , root_url : String ) -> Result < Self > {
4849 // guarantee a trailing slash, otherwise join will drop the last component
@@ -70,6 +71,8 @@ impl TmcCore {
7071 ///
7172 /// # Examples
7273 /// ```rust,no_run
74+ /// use tmc_langs_core::TmcCore;
75+ ///
7376 /// let core = TmcCore::new_in_config("https://tmc.mooc.fi".to_string()).unwrap();
7477 /// ```
7578 pub fn new_in_config ( root_url : String ) -> Result < Self > {
@@ -87,6 +90,8 @@ impl TmcCore {
8790 ///
8891 /// # Examples
8992 /// ```rust,no_run
93+ /// use tmc_langs_core::TmcCore;
94+ ///
9095 /// let mut core = TmcCore::new_in_config("https://tmc.mooc.fi".to_string()).unwrap();
9196 /// core.authenticate("client", "user".to_string(), "pass".to_string()).unwrap();
9297 /// ```
@@ -96,6 +101,59 @@ impl TmcCore {
96101 email : String ,
97102 password : String ,
98103 ) -> Result < ( ) > {
104+ // required until oauth 4.x.x
105+ fn custom_client < ' a > (
106+ client : & ' a Client ,
107+ ) -> impl FnOnce ( oauth2:: HttpRequest ) -> Result < oauth2:: HttpResponse > + ' a {
108+ move |req| {
109+ // convert httprequest fields
110+ let method = http:: method:: Method :: from_bytes ( req. method . as_str ( ) . as_bytes ( ) ) ?;
111+ let mut headers = http:: HeaderMap :: new ( ) ;
112+ let mut next_key = None ;
113+ for ( key, val) in req. headers {
114+ // if key is none, keep using previous next key
115+ if key. is_some ( ) {
116+ // update next key
117+ next_key = key;
118+ }
119+ let header_name = if let Some ( name) = next_key. as_ref ( ) {
120+ // use next key
121+ name
122+ } else {
123+ log:: error!( "invalid header map, found None key first" ) ;
124+ continue ;
125+ } ;
126+ let header_name =
127+ http:: header:: HeaderName :: from_bytes ( header_name. as_str ( ) . as_bytes ( ) ) ?;
128+ let header_value = http:: header:: HeaderValue :: from_bytes ( val. as_bytes ( ) ) ?;
129+ headers. insert ( header_name, header_value) ;
130+ }
131+ let res = client
132+ . request ( method, req. url )
133+ . headers ( headers)
134+ . body ( req. body )
135+ . send ( ) ?;
136+
137+ // convert response to httpresponse
138+ let status_code = http1:: StatusCode :: from_bytes ( res. status ( ) . as_str ( ) . as_bytes ( ) ) ?;
139+ let mut headers = http1:: HeaderMap :: new ( ) ;
140+ for ( key, val) in res. headers ( ) {
141+ let header_name =
142+ http1:: header:: HeaderName :: from_bytes ( key. as_str ( ) . as_bytes ( ) ) ?;
143+ let header_value = http1:: header:: HeaderValue :: from_bytes ( val. as_bytes ( ) ) ?;
144+ headers. insert ( header_name, header_value) ;
145+ }
146+ let body = res. bytes ( ) ?. to_vec ( ) ;
147+ let res = oauth2:: HttpResponse {
148+ status_code,
149+ headers,
150+ body,
151+ } ;
152+
153+ Ok ( res)
154+ }
155+ }
156+
99157 if self . token . is_some ( ) {
100158 return Err ( CoreError :: AlreadyAuthenticated ) ;
101159 }
@@ -105,26 +163,20 @@ impl TmcCore {
105163 . join ( & format ! ( "application/{}/credentials" , client_name) ) ?;
106164 let credentials: Credentials = self . get_json_from_url ( url) ?;
107165
108- let auth_url = Url1 :: parse ( self . auth_url . as_str ( ) ) ?;
109- log:: debug!( "authenticating at {}" , auth_url) ;
166+ log:: debug!( "authenticating at {}" , self . auth_url) ;
110167 let client = BasicClient :: new (
111168 ClientId :: new ( credentials. application_id ) ,
112169 Some ( ClientSecret :: new ( credentials. secret ) ) ,
113- AuthUrl :: new ( auth_url. clone ( ) ) , // not used in the Resource Owner Password Credentials Grant
114- Some ( TokenUrl :: new ( auth_url) ) ,
170+ AuthUrl :: new ( self . auth_url . as_str ( ) . to_string ( ) ) ? , // not used in the Resource Owner Password Credentials Grant
171+ Some ( TokenUrl :: new ( self . auth_url . as_str ( ) . to_string ( ) ) ? ) ,
115172 ) ;
116173
117174 let token = client
118175 . exchange_password (
119176 & ResourceOwnerUsername :: new ( email) ,
120177 & ResourceOwnerPassword :: new ( password) ,
121178 )
122- . map_err ( |e| match e {
123- oauth2:: RequestTokenError :: Parse ( e, msg) => {
124- CoreError :: TokenParse ( e, String :: from_utf8_lossy ( & msg) . into_owned ( ) )
125- }
126- _ => CoreError :: Token ( e) ,
127- } ) ?;
179+ . request ( custom_client ( & self . client ) ) ?;
128180 self . token = Some ( token) ;
129181 log:: debug!( "authenticated" ) ;
130182 Ok ( ( ) )
@@ -152,6 +204,9 @@ impl TmcCore {
152204 ///
153205 /// # Examples
154206 /// ```rust,no_run
207+ /// use tmc_langs_core::TmcCore;
208+ /// use std::path::Path;
209+ ///
155210 /// let core = TmcCore::new_in_config("https://tmc.mooc.fi".to_string()).unwrap();
156211 /// // authenticate
157212 /// core.download_or_update_exercises(vec![
@@ -274,10 +329,12 @@ impl TmcCore {
274329 ///
275330 /// # Examples
276331 /// ```rust,no_run
332+ /// use tmc_langs_core::TmcCore;
333+ ///
277334 /// let core = TmcCore::new_in_config("https://tmc.mooc.fi".to_string()).unwrap();
278335 /// // authenticate
279336 /// let mut checksums = std::collections::HashMap::new();
280- /// checksums.insert(1234, "exercisechecksum");
337+ /// checksums.insert(1234, "exercisechecksum".to_string() );
281338 /// let update_result = core.get_exercise_updates(600, checksums).unwrap();
282339 /// ```
283340 pub fn get_exercise_updates (
0 commit comments