add POST /login/oauth/access_token
				
					
				
			This commit is contained in:
		
							parent
							
								
									716192d4d4
								
							
						
					
					
						commit
						bf8d6e1a3b
					
				
					 1 changed files with 66 additions and 2 deletions
				
			
		
							
								
								
									
										68
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										68
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,8 +11,6 @@ pub struct Forgejo {
 | 
			
		|||
 | 
			
		||||
mod generated;
 | 
			
		||||
 | 
			
		||||
pub use generated::structs;
 | 
			
		||||
 | 
			
		||||
#[derive(thiserror::Error, Debug)]
 | 
			
		||||
pub enum ForgejoError {
 | 
			
		||||
    #[error("url must have a host")]
 | 
			
		||||
| 
						 | 
				
			
			@ -154,6 +152,22 @@ impl Forgejo {
 | 
			
		|||
        Ok(self.execute(request).await?.bytes().await?)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Requests a new OAuth2 access token
 | 
			
		||||
    ///
 | 
			
		||||
    /// More info at [Forgejo's docs](https://forgejo.org/docs/latest/user/oauth2-provider).
 | 
			
		||||
    pub async fn oauth_get_access_token(
 | 
			
		||||
        &self,
 | 
			
		||||
        body: structs::OAuthTokenRequest<'_>,
 | 
			
		||||
    ) -> Result<structs::OAuthToken, ForgejoError> {
 | 
			
		||||
        let url = self.url.join("login/oauth/access_token").unwrap();
 | 
			
		||||
        let request = self.client.post(url).json(&body).build()?;
 | 
			
		||||
        let response = self.execute(request).await?;
 | 
			
		||||
        match response.status().as_u16() {
 | 
			
		||||
            200 => Ok(response.json().await?),
 | 
			
		||||
            _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get(&self, path: &str) -> reqwest::RequestBuilder {
 | 
			
		||||
        let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
 | 
			
		||||
        self.client.get(url)
 | 
			
		||||
| 
						 | 
				
			
			@ -202,6 +216,56 @@ struct ErrorMessage {
 | 
			
		|||
    // url: Url
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub mod structs {
 | 
			
		||||
    pub use crate::generated::structs::*;
 | 
			
		||||
 | 
			
		||||
    /// A Request for a new OAuth2 access token
 | 
			
		||||
    ///
 | 
			
		||||
    /// More info at [Forgejo's docs](https://forgejo.org/docs/latest/user/oauth2-provider).
 | 
			
		||||
    #[derive(serde::Serialize)]
 | 
			
		||||
    #[serde(tag = "grant_type")]
 | 
			
		||||
    pub enum OAuthTokenRequest<'a> {
 | 
			
		||||
        /// Request for getting an access code for a confidential app
 | 
			
		||||
        ///
 | 
			
		||||
        /// The `code` field must have come from sending the user to
 | 
			
		||||
        /// `/login/oauth/authorize` in their browser
 | 
			
		||||
        #[serde(rename = "authorization_code")]
 | 
			
		||||
        Confidential {
 | 
			
		||||
            client_id: &'a str,
 | 
			
		||||
            client_secret: &'a str,
 | 
			
		||||
            code: &'a str,
 | 
			
		||||
            redirect_uri: url::Url,
 | 
			
		||||
        },
 | 
			
		||||
        /// Request for getting an access code for a public app
 | 
			
		||||
        ///
 | 
			
		||||
        /// The `code` field must have come from sending the user to
 | 
			
		||||
        /// `/login/oauth/authorize` in their browser
 | 
			
		||||
        #[serde(rename = "authorization_code")]
 | 
			
		||||
        Public {
 | 
			
		||||
            client_id: &'a str,
 | 
			
		||||
            code_verifier: &'a str,
 | 
			
		||||
            code: &'a str,
 | 
			
		||||
            redirect_uri: url::Url,
 | 
			
		||||
        },
 | 
			
		||||
        /// Request for refreshing an access code
 | 
			
		||||
        #[serde(rename = "refresh_token")]
 | 
			
		||||
        Refresh {
 | 
			
		||||
            refresh_token: &'a str,
 | 
			
		||||
            client_id: &'a str,
 | 
			
		||||
            client_secret: &'a str,
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(serde::Deserialize)]
 | 
			
		||||
    pub struct OAuthToken {
 | 
			
		||||
        pub access_token: String,
 | 
			
		||||
        pub refresh_token: String,
 | 
			
		||||
        pub token_type: String,
 | 
			
		||||
        /// Number of seconds until the access token expires.
 | 
			
		||||
        pub expires_in: u32,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Forgejo can return blank strings for URLs. This handles that by deserializing
 | 
			
		||||
// that as `None`
 | 
			
		||||
fn none_if_blank_url<'de, D: serde::Deserializer<'de>>(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue