Basic GitHub integration
This commit is contained in:
parent
88c0b8a8f0
commit
34075738ea
3
.env
3
.env
@ -20,3 +20,6 @@ MAX_CURSEFORGE_ID=450000
|
|||||||
LOCAL_INDEX_INTERVAL=3600
|
LOCAL_INDEX_INTERVAL=3600
|
||||||
# 12 hours
|
# 12 hours
|
||||||
EXTERNAL_INDEX_INTERVAL=43200
|
EXTERNAL_INDEX_INTERVAL=43200
|
||||||
|
|
||||||
|
GITHUB_CLIENT_ID=3acffb2e808d16d4b226
|
||||||
|
GITHUB_CLIENT_SECRET=none
|
||||||
@ -1,4 +1,4 @@
|
|||||||
use log::{debug, info};
|
use log::info;
|
||||||
use sqlx::migrate::{Migrate, MigrateDatabase, Migrator};
|
use sqlx::migrate::{Migrate, MigrateDatabase, Migrator};
|
||||||
use sqlx::postgres::{PgPool, PgPoolOptions};
|
use sqlx::postgres::{PgPool, PgPoolOptions};
|
||||||
use sqlx::{Connection, PgConnection, Postgres};
|
use sqlx::{Connection, PgConnection, Postgres};
|
||||||
|
|||||||
@ -193,6 +193,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.service(routes::index_get)
|
.service(routes::index_get)
|
||||||
.service(
|
.service(
|
||||||
web::scope("/api/v1/")
|
web::scope("/api/v1/")
|
||||||
|
.configure(routes::auth_config)
|
||||||
.configure(routes::tags_config)
|
.configure(routes::tags_config)
|
||||||
.configure(routes::mods_config),
|
.configure(routes::mods_config),
|
||||||
)
|
)
|
||||||
@ -246,4 +247,7 @@ fn check_env_vars() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_var::<usize>("LOCAL_INDEX_INTERVAL");
|
check_var::<usize>("LOCAL_INDEX_INTERVAL");
|
||||||
|
|
||||||
|
check_var::<String>("GITHUB_CLIENT_ID");
|
||||||
|
check_var::<String>("GITHUB_CLIENT_SECRET");
|
||||||
}
|
}
|
||||||
|
|||||||
84
src/routes/auth.rs
Normal file
84
src/routes/auth.rs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
use crate::models::error::ApiError;
|
||||||
|
use log::{info};
|
||||||
|
use actix_web::web::{Query, ServiceConfig, scope};
|
||||||
|
use actix_web::{get, HttpResponse};
|
||||||
|
use actix_web::http::StatusCode;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
pub fn config(cfg: &mut ServiceConfig) {
|
||||||
|
cfg.service(auth_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum AuthorizationError {
|
||||||
|
#[error("Environment Error")]
|
||||||
|
EnvError(#[from] dotenv::Error),
|
||||||
|
#[error("An unknown database error occured")]
|
||||||
|
SqlxDatabaseError(#[from] sqlx::Error),
|
||||||
|
#[error("Database Error: {0}")]
|
||||||
|
DatabaseError(#[from] crate::database::models::DatabaseError),
|
||||||
|
#[error("Error while parsing JSON: {0}")]
|
||||||
|
SerDeError(#[from] serde_json::Error),
|
||||||
|
#[error("Error while communicating to GitHub OAuth2")]
|
||||||
|
GithubError(#[from] reqwest::Error),
|
||||||
|
}
|
||||||
|
// "https://github.com/login/oauth/authorize?client_id=3acffb2e808d16d4b226&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fapi%2Fv1%2Fauthcallback"
|
||||||
|
impl actix_web::ResponseError for AuthorizationError {
|
||||||
|
fn status_code(&self) -> StatusCode {
|
||||||
|
match self {
|
||||||
|
AuthorizationError::EnvError(..) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
AuthorizationError::SqlxDatabaseError(..) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
AuthorizationError::DatabaseError(..) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
AuthorizationError::SerDeError(..) => StatusCode::BAD_REQUEST,
|
||||||
|
AuthorizationError::GithubError(..) => StatusCode::FAILED_DEPENDENCY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_response(&self) -> HttpResponse {
|
||||||
|
HttpResponse::build(self.status_code()).json(ApiError {
|
||||||
|
error: match self {
|
||||||
|
AuthorizationError::EnvError(..) => "environment_error",
|
||||||
|
AuthorizationError::SqlxDatabaseError(..) => "database_error",
|
||||||
|
AuthorizationError::DatabaseError(..) => "database_error",
|
||||||
|
AuthorizationError::SerDeError(..) => "invalid_input",
|
||||||
|
AuthorizationError::GithubError(..) => "github_error",
|
||||||
|
},
|
||||||
|
description: &self.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Authorization {
|
||||||
|
pub code: String,
|
||||||
|
pub state: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct AccessToken {
|
||||||
|
pub access_token: String,
|
||||||
|
pub scope: String,
|
||||||
|
pub token_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("authcallback")]
|
||||||
|
pub async fn auth_callback(Query(info): Query<Authorization>) -> Result<HttpResponse, AuthorizationError> {
|
||||||
|
let client_id = dotenv::var("GITHUB_CLIENT_ID")?;
|
||||||
|
let client_secret = dotenv::var("GITHUB_CLIENT_SECRET")?;
|
||||||
|
|
||||||
|
let url = format!(
|
||||||
|
"https://github.com/login/oauth/access_token?client_id={}&client_secret={}&code={}",
|
||||||
|
client_id, client_secret, info.code
|
||||||
|
);
|
||||||
|
|
||||||
|
let token : AccessToken = reqwest::Client::new()
|
||||||
|
.post(&url)
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.json()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(token))
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
|
|
||||||
|
mod auth;
|
||||||
mod index;
|
mod index;
|
||||||
mod mod_creation;
|
mod mod_creation;
|
||||||
mod mods;
|
mod mods;
|
||||||
@ -9,6 +10,7 @@ mod version_creation;
|
|||||||
mod versions;
|
mod versions;
|
||||||
|
|
||||||
pub use tags::config as tags_config;
|
pub use tags::config as tags_config;
|
||||||
|
pub use auth::config as auth_config;
|
||||||
|
|
||||||
pub use self::index::index_get;
|
pub use self::index::index_get;
|
||||||
pub use self::not_found::not_found;
|
pub use self::not_found::not_found;
|
||||||
|
|||||||
@ -63,9 +63,9 @@ pub async fn index_mods(pool: PgPool, settings: IndexingSettings) -> Result<(),
|
|||||||
}
|
}
|
||||||
if settings.index_external {
|
if settings.index_external {
|
||||||
let end_index = dotenv::var("MAX_CURSEFORGE_ID")
|
let end_index = dotenv::var("MAX_CURSEFORGE_ID")
|
||||||
.ok()
|
.ok()
|
||||||
.map(|i| i.parse().unwrap())
|
.map(|i| i.parse().unwrap())
|
||||||
.unwrap_or(450_000);
|
.unwrap_or(450_000);
|
||||||
|
|
||||||
docs_to_add.append(&mut index_curseforge(1, end_index).await?);
|
docs_to_add.append(&mut index_curseforge(1, end_index).await?);
|
||||||
}
|
}
|
||||||
@ -271,7 +271,11 @@ fn default_settings() -> Settings {
|
|||||||
.with_searchable_attributes(searchable_attributes)
|
.with_searchable_attributes(searchable_attributes)
|
||||||
.with_stop_words(vec![])
|
.with_stop_words(vec![])
|
||||||
.with_synonyms(HashMap::new())
|
.with_synonyms(HashMap::new())
|
||||||
.with_attributes_for_faceting(vec![String::from("categories"), String::from("host"), String::from("versions")])
|
.with_attributes_for_faceting(vec![
|
||||||
|
String::from("categories"),
|
||||||
|
String::from("host"),
|
||||||
|
String::from("versions"),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
@ -5,8 +5,7 @@ use actix_web::web::HttpResponse;
|
|||||||
use meilisearch_sdk::client::Client;
|
use meilisearch_sdk::client::Client;
|
||||||
use meilisearch_sdk::document::Document;
|
use meilisearch_sdk::document::Document;
|
||||||
use meilisearch_sdk::search::Query;
|
use meilisearch_sdk::search::Query;
|
||||||
use serde::ser::SerializeStruct;
|
use serde::{Deserialize, Serialize};
|
||||||
use serde::{Deserialize, Serialize, Serializer};
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user