2020-10-26 16:56:24 +00:00
|
|
|
#![feature(proc_macro_hygiene, decl_macro)]
|
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
extern crate diesel;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate rocket;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate rocket_contrib;
|
|
|
|
|
2020-10-27 15:43:54 +00:00
|
|
|
use color_eyre::eyre::Result;
|
2020-10-26 16:56:24 +00:00
|
|
|
use diesel::pg::PgConnection;
|
|
|
|
use diesel::prelude::*;
|
2020-10-27 15:43:54 +00:00
|
|
|
use rocket::{
|
|
|
|
http::{Cookie, Cookies, SameSite},
|
|
|
|
response::Redirect,
|
|
|
|
};
|
2020-10-28 16:20:00 +00:00
|
|
|
use rocket_contrib::helmet::SpaceHelmet;
|
2020-10-27 15:43:54 +00:00
|
|
|
use rocket_oauth2::{OAuth2, TokenResponse};
|
2020-10-26 16:56:24 +00:00
|
|
|
|
2020-10-28 01:07:25 +00:00
|
|
|
pub mod api;
|
2020-10-27 15:43:54 +00:00
|
|
|
pub mod gitea;
|
2020-10-28 16:20:00 +00:00
|
|
|
pub mod jwt;
|
2020-10-26 16:56:24 +00:00
|
|
|
pub mod models;
|
|
|
|
pub mod schema;
|
|
|
|
|
|
|
|
#[database("main_data")]
|
2020-10-28 01:07:25 +00:00
|
|
|
pub struct MainDatabase(PgConnection);
|
2020-10-26 16:56:24 +00:00
|
|
|
|
2020-10-28 16:20:00 +00:00
|
|
|
pub struct Gitea;
|
2020-10-27 15:43:54 +00:00
|
|
|
|
|
|
|
#[tracing::instrument(skip(oauth2, cookies))]
|
|
|
|
#[get("/login/gitea")]
|
|
|
|
fn gitea_login(oauth2: OAuth2<Gitea>, mut cookies: Cookies<'_>) -> Redirect {
|
|
|
|
oauth2.get_redirect(&mut cookies, &[""]).unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(skip(conn, token, cookies))]
|
|
|
|
#[get("/auth/gitea")]
|
|
|
|
fn gitea_callback(
|
|
|
|
conn: MainDatabase,
|
|
|
|
token: TokenResponse<Gitea>,
|
|
|
|
mut cookies: Cookies<'_>,
|
2020-10-28 16:20:00 +00:00
|
|
|
) -> String {
|
2020-10-27 15:43:54 +00:00
|
|
|
let tok = token.access_token().to_string();
|
|
|
|
let refresh = token.refresh_token().unwrap().to_string();
|
|
|
|
|
2020-10-27 16:21:28 +00:00
|
|
|
let gitea_user = gitea::user(tok.clone()).expect("gitea api call to work");
|
|
|
|
|
|
|
|
use schema::{
|
2020-10-28 16:20:00 +00:00
|
|
|
gitea_tokens, tokens,
|
2020-10-27 16:21:28 +00:00
|
|
|
users::{
|
|
|
|
dsl::{email, users},
|
|
|
|
table as users_table,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
let user: models::User = match users
|
|
|
|
.filter(email.eq(gitea_user.email.clone()))
|
|
|
|
.limit(1)
|
|
|
|
.load::<models::User>(&*conn)
|
|
|
|
{
|
2020-10-28 16:20:00 +00:00
|
|
|
Ok(u) => {
|
|
|
|
if u.len() == 0 {
|
|
|
|
let u = models::NewUser {
|
|
|
|
salutation: gitea_user.full_name,
|
|
|
|
email: gitea_user.email,
|
|
|
|
is_admin: gitea_user.is_admin,
|
|
|
|
is_locked: false,
|
|
|
|
tier: 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
let u: models::User = diesel::insert_into(users_table)
|
|
|
|
.values(&u)
|
|
|
|
.get_result(&*conn)
|
|
|
|
.expect("able to insert user");
|
|
|
|
|
|
|
|
let tok = models::NewGiteaToken {
|
|
|
|
user_id: u.id.clone(),
|
|
|
|
access_token: tok,
|
|
|
|
refresh_token: refresh,
|
|
|
|
};
|
|
|
|
|
|
|
|
let _: models::GiteaToken = diesel::insert_into(gitea_tokens::table)
|
|
|
|
.values(&tok)
|
|
|
|
.get_result(&*conn)
|
|
|
|
.expect("able to insert token");
|
|
|
|
|
|
|
|
u
|
|
|
|
} else {
|
|
|
|
tracing::info!("{} {:?} logged in", u[0].id, u[0].salutation);
|
|
|
|
u[0].clone()
|
|
|
|
}
|
|
|
|
}
|
2020-10-27 17:41:34 +00:00
|
|
|
Err(why) => {
|
|
|
|
tracing::error!("error reading from database: {}", why);
|
|
|
|
todo!("error response")
|
2020-10-27 15:43:54 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-10-28 16:20:00 +00:00
|
|
|
let tok: models::Token = diesel::insert_into(tokens::table)
|
|
|
|
.values(&models::NewToken {
|
|
|
|
user_id: user.id.clone(),
|
|
|
|
})
|
|
|
|
.get_result(&*conn)
|
|
|
|
.expect("create token information");
|
|
|
|
tracing::info!("created new token for {} with id {}", user.id, tok.id);
|
|
|
|
|
|
|
|
let tok = jwt::make(user.id, tok.id).expect("to sign JWT");
|
2020-10-27 15:43:54 +00:00
|
|
|
// Set a private cookie with the access token
|
|
|
|
cookies.add_private(
|
2020-10-28 16:20:00 +00:00
|
|
|
Cookie::build("token", tok.clone())
|
2020-10-27 15:43:54 +00:00
|
|
|
.same_site(SameSite::Lax)
|
|
|
|
.finish(),
|
|
|
|
);
|
|
|
|
|
2020-10-28 16:20:00 +00:00
|
|
|
tok
|
2020-10-27 15:43:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> Result<()> {
|
|
|
|
color_eyre::install()?;
|
|
|
|
tracing_subscriber::fmt::init();
|
|
|
|
|
2020-10-28 16:20:00 +00:00
|
|
|
tracing::trace!("JWT secret: {:?}", *jwt::SECRET);
|
2020-10-26 16:56:24 +00:00
|
|
|
rocket::ignite()
|
2020-10-27 15:43:54 +00:00
|
|
|
.attach(OAuth2::<Gitea>::fairing("gitea"))
|
2020-10-26 16:56:24 +00:00
|
|
|
.attach(MainDatabase::fairing())
|
2020-10-27 15:43:54 +00:00
|
|
|
.attach(SpaceHelmet::default())
|
2020-10-28 01:07:25 +00:00
|
|
|
.mount("/api", routes![api::get_user])
|
2020-10-27 15:43:54 +00:00
|
|
|
.mount("/", routes![gitea_login, gitea_callback])
|
|
|
|
.launch();
|
|
|
|
|
|
|
|
Ok(())
|
2020-10-26 16:56:24 +00:00
|
|
|
}
|