wip: connect to github

This commit is contained in:
2026-04-24 19:22:25 +01:00
parent b327648d31
commit a9f4d1d923
11 changed files with 587 additions and 146 deletions

View File

@@ -1,17 +1,24 @@
use std::collections::HashMap;
use serde::Deserialize;
use crate::{api, query};
use crate::{
api,
query::{self, use_query},
};
pub(crate) const DEVICE_LOGIN_FLOW_URL: &str = "https://github.com/login/device";
#[derive(Clone)]
pub struct CreateDeviceCode;
#[derive(Deserialize)]
pub struct DeviceCodeResponse {
device_code: String,
user_code: String,
vertification_uri: String,
expires_in: u16,
interval: u16,
pub(crate) struct DeviceCodeResponse {
pub device_code: String,
pub user_code: String,
pub vertification_uri: Option<String>,
pub expires_in: u16,
pub interval: u16,
}
impl query::QueryFn for CreateDeviceCode {
@@ -24,17 +31,57 @@ impl query::QueryFn for CreateDeviceCode {
}
async fn run(&self, c: &Self::Context) -> Result<Self::Data, Self::Error> {
let data = c
let res = c
.http
.post(format!(
"https://github.com/login/device/code?client_id={}",
c.github.client_id
))
.header("Accept", "application/json")
.send()
.await?
.bytes()
.await?;
serde_json::from_slice::<DeviceCodeResponse>(&data).map_err(|e| e.into())
api::parse_response(res).await
}
}
#[derive(Clone)]
pub struct RequestAccessToken {
pub device_code: String,
}
#[derive(Deserialize)]
pub struct RequestAccessTokenResponse {
pub access_token: String,
pub token_type: String,
pub scope: String,
}
impl query::QueryFn for RequestAccessToken {
type Data = RequestAccessTokenResponse;
type Error = api::Error;
type Context = api::QueryContext;
fn key(&self) -> &'static str {
"auth.access_token"
}
async fn run(&self, c: &Self::Context) -> Result<Self::Data, Self::Error> {
let mut params = HashMap::new();
params.insert("client_id", c.github.client_id);
params.insert("device_code", &self.device_code);
params.insert("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
let res = c
.http
.post(format!(
"https://github.com/login/oauth/access_token?client_id={}&device_code={}",
c.github.client_id, self.device_code
))
.form(&params)
.send()
.await?;
api::parse_response(res).await
}
}

View File

@@ -1,10 +1,23 @@
use reqwest::Method;
use serde::Deserialize;
use crate::{api, query};
#[derive(Debug, Deserialize)]
pub struct User {
pub login: String,
pub id: u64,
pub avatar_url: String,
pub html_url: String,
pub name: Option<String>,
pub email: Option<String>,
}
#[derive(Clone)]
pub struct Fetch;
impl query::QueryFn for Fetch {
type Data = api::Error;
type Data = User;
type Error = api::Error;
type Context = api::QueryContext;
@@ -13,6 +26,7 @@ impl query::QueryFn for Fetch {
}
async fn run(&self, c: &Self::Context) -> Result<Self::Data, Self::Error> {
Err(api::Error::Unauthenticated)
let res = c.github_request(Method::GET, "/user")?.send().await?;
api::parse_response(res).await
}
}